如何用spring生成接口的代理对象并让接口能使用

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何用spring生成接口的代理对象并让接口能使用相关的知识,希望对你有一定的参考价值。

参考技术A 1、自动扫描classpath下的注解类
2、生成代理Bean 注册到 spring容器本回答被提问者采纳

spring再学习之AOP准备

一、aop思想:

横向重复,纵向抽取

1、乱码

2、事务管理

3,action

 

二、spring能够为容器中管理的对象生成代理对象

1、spring能帮我们生成代理对象

2、spring实现aop的原理

(1)动态代理(优先)

被代理对象必须要实现接口,才能产生代理对象,如果没有接口将不能使用动态代理技术

 

(2)cglib代理

第三方代理技术,cglib,可以对任何类生成代理,代理的原理是对目标对象进行继承代理,如果

目标对象被final修饰,那么该类无法被cglib代理。

3,上代码

(1)接口

package cn.itcast.service;

public interface UserService {
    void save();
    void delete();
    void update();
    void find();
}

(2)实现类

package cn.itcast.service;

public class UserServiceImpl implements UserService {
    @Override
    public void save() {
        System.out.println("保存用户!");
        //int i = 1/0;
    }
    @Override
    public void delete() {
        System.out.println("删除用户!");
    }
    @Override
    public void update() {
        System.out.println("更新用户!");
    }
    @Override
    public void find() {
        System.out.println("查找用户!");
    }
}

(3)动态代理代码

//观光代码=>动态代理
public class UserServiceProxyFactory implements InvocationHandler {
    
    public UserServiceProxyFactory(UserService us) {
        super();
        this.us = us;
    }

    private UserService us;
    
    public UserService getUserServiceProxy(){
        //生成动态代理
        UserService usProxy = (UserService) Proxy.newProxyInstance(UserServiceProxyFactory.class.getClassLoader(),
                                    UserServiceImpl.class.getInterfaces(), 
                                    this);
        //返回
        return usProxy;
        
    }

    @Override
    public Object invoke(Object arg0, Method method, Object[] arg2) throws Throwable {
        System.out.println("打开事务!");
        Object invoke = method.invoke(us, arg2);//原方法
        System.out.println("提交事务!");
        return invoke;
    }

}

测试:

@Test
    //动态代理
    public void fun1(){
        UserService us = new UserServiceImpl();
        
        UserServiceProxyFactory factory = new UserServiceProxyFactory(us);
        
        UserService usProxy = factory.getUserServiceProxy();
        
        usProxy.save();
        
        //代理对象与被代理对象实现了相同的接口
        //代理对象 与 被代理对象没有继承关系 
        //System.out.println(usProxy instanceof UserServiceImpl );//false
    }

 

结果:

打开事务!
保存用户!     
提交事务!   

 

(4)cglib代理

//观光代码=>cglib代理
public class UserServiceProxyFactory2 implements MethodInterceptor {
    

    public UserService getUserServiceProxy(){
        
        Enhancer en = new Enhancer();//帮我们生成代理对象
        
        en.setSuperclass(UserServiceImpl.class);//设置对谁进行代理
        
        en.setCallback(this);//代理要做什么
        
        UserService us = (UserService) en.create();//创建代理对象
        
        return us;
    }

    @Override
    public Object intercept(Object prxoyobj, Method method, Object[] arg, MethodProxy methodProxy) throws Throwable {
        //打开事务
        System.out.println("打开事务!");
        //调用原有方法
        Object returnValue = methodProxy.invokeSuper(prxoyobj, arg);
        //提交事务
        System.out.println("提交事务!");
        
        return returnValue;
    }


}

测试:

   @Test
    public void fun2(){
        
        UserServiceProxyFactory2 factory = new UserServiceProxyFactory2();
        
        UserService usProxy = factory.getUserServiceProxy();
        
        usProxy.save();
        
        //判断代理对象是否属于被代理对象类型
        //代理对象继承了被代理对象=>true
        //System.out.println(usProxy instanceof UserServiceImpl );//true
    }

 

结果:

打开事务!
保存用户!     
提交事务! 

三、AOP中的名词:

joinpoint(连接点):目标对象中,所有可以增强的方法

pointcut(切入点):目标对象,已经增强的方法

Advice(通知/增强):增强的代码

Target(目标对象):被代理对象

weaving(织如):将通知应用带切入点的过程

Proxy(代理):将通知织如到目标对象之后,形成代理对象

aspect(切面):切入点+通知

 

以上是关于如何用spring生成接口的代理对象并让接口能使用的主要内容,如果未能解决你的问题,请参考以下文章

如何用Java动态代理实现AOP

使用spring通知时,代理出错

Spring事务常见的坑

spring中AOP

一个类实现两个接口,如何用spring实例化

spring aop中this和target区别