Sping之AOP思想

Posted xiejiangping

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Sping之AOP思想相关的知识,希望对你有一定的参考价值。

AOP是指面向切面编程,横向重复,纵向提取。在最早接触AOP思想是从servlet开始的,代码如下,设置字符集,通过filter统一设置。

1 @Override
2     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
3             throws IOException, ServletException {
4         request.setCharacterEncoding("UTF-8");
5         chain.doFilter(request, response);
6         response.setCharacterEncoding("UTF-8");
7     }

再有就是再学习Struts2框架时接触到的拦截器栈。有国际化,参数封装,模型驱动,异常等等拦截器。

接着就是Spring的AOP思想,先说结论,Spring的AOP思想是通过动态代理和cglib代理实现,前者优先。

 

动态代理解释:被代理的对象必须要实现接口,动态代理对象相当于这个接口的实现类,是对被代理对象的扩展。可以看出动态代理是由局限性的,要求被代理对象要实现某个接口。

cglib代理解释:是一个第三方代理,是对被代理对象的继承代理,从而进行扩展。

代码演示

定义接口

1 public interface UserService {
2     void save();
3     void delete();
4     void update();
5     void select();
6 }

实现接口

 1 public class  UserServiceImpl implements UserService{
 2     @Override
 3     public void save() {
 4         System.out.println("调用dao的保存方法");
 5     }
 6     
 7     @Override
 8     public void delete() {
 9         System.out.println("调用dao的删除方法");
10     }
11     
12     @Override
13     public void update() {
14         
15         System.out.println("调用dao的更新方法");
16     }
17     
18     @Override
19     public void select() {
20         
21         System.out.println("调用dao的查询方法");
22     }
23 }

动态代理演示

 1 /**
 2  * 动态代理
 3  * @author 67471
 4  *
 5  */
 6 public class ProxyUservice implements InvocationHandler{
 7     private UserService userService;
 8     
 9     public ProxyUservice(UserService userService) {
10         super();
11         this.userService = userService;
12     }
13 
14     public  UserService getUserviceProxy(){
15         //获得代理对象
16         UserService userServiceProxy =  (UserService) Proxy.newProxyInstance(ProxyUservice.class.getClassLoader(),
17                                                                 UserServiceImpl.class.getInterfaces(),
18                                                                 this);
19         return userServiceProxy;
20     }
21 
22     //要增强的内容
23     @Override
24     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
25         System.out.println("开启事务");
26         Object invoke = method.invoke(userService, args);
27         System.out.println("提交事务");
28         return invoke;
29     }
30 }

测试代码

 1 public class ProxyTest {
 2     public static void main(String[] args) {
 3                 //获得代理对象
 4         ProxyUservice proxyUservice = new ProxyUservice(new UserServiceImpl());
 5         UserService userviceProxy = proxyUservice.getUserviceProxy();
 6         userviceProxy.save();
 7                 //判断代理对象是被代理对象类型
 8         System.out.println(userviceProxy instanceof UserServiceImpl);
 9     }
10 }            

结果

开启事务
调用dao的保存方法
提交事务
false

cglib代理演示

ublic class Cglibproxy implements MethodInterceptor{
    private UserServiceImpl usi;
    
    public Cglibproxy(UserServiceImpl usi) {
        super();
        this.usi = usi;
    }
    public  UserService getUserviceProxy(){
        Enhancer en = new Enhancer();//生成代理对象的对象
        en.setSuperclass(UserServiceImpl.class);//cglib代理是继承代理,需要我们指定父类,所以父类不要用final修饰
        en.setCallback(this);//指定增强的内容
        UserServiceImpl userServiceImplProxy = (UserServiceImpl) en.create();//创建代理对象
        return userServiceImplProxy;
        
    }
    @Override
    public Object intercept(Object arg0, Method method, Object[] arg2, MethodProxy arg3) throws Throwable {
        System.out.println("开启事务");
        Object invoke = method.invoke(usi, arg2);//需要指定方法的参数和目标对象
        System.out.println("提交事务");
        return invoke;
    }

}

测试代码

public class ProxyTest2 {
    public static void main(String[] args) {
               //获得代理对象
        Cglibproxy cglibproxy = new Cglibproxy(new UserServiceImpl());
        UserService userviceProxy = cglibproxy.getUserviceProxy();
        userviceProxy.save();
        //判断代理对象是被代理对象类型吗
                System.out.println(userviceProxy instanceof UserServiceImpl);
    }
}    

结果:

开启事务
调用dao的保存方法
提交事务
true

 

以上是关于Sping之AOP思想的主要内容,如果未能解决你的问题,请参考以下文章

Sping Aop日志实现--日志查询功能

JAVA之AOP

sping aop 源码分析

Sping Aop日志实现--使用Mybatis注解保存日志

sping 03--21

Sping AOP Capabilities and Goals