Java代理及Spring AOP

Posted jameszheng

tags:

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

Spring的AOP核心采用的设计模式采用的是代理模式,先介绍下Java的代理。

这里借鉴一下其他人的介绍,https://blog.csdn.net/fighterandknight/article/details/51200470

一 代理模式

代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。 

1.静态代理

先定义接口是实现类:

public interface Test{  

        public void test();  
      
}
      
public class TestImpl implements Test{  
      
        @Override  
        public void test() {  
            System.out.println("测试方法...");  
      
        }  

      
    }  

添加代理类:

 1 public class TestProxy implements Test{  
 2         private TestImpl testImpl;  
 3       
 4         /** 
 5          * 覆盖默认构造器 
 6          *  
 7          * 
 8          */  
 9         public TestProxy (TestImpl testImpl) {  
10             this.testImpl= testImpl;  
11         }  
12       
13         @Override  
14         public void test() {  
15             System.out.println("事务处理之前");  
16             // 调用委托类的方法;  
17             testImpl.test();  
18             System.out.println("事务处理之后");  
19         }  
20 }
21       

测试类:

1 public class TestCount {  
2         public static void main(String[] args) {  
3             TestImpl testImpl = new TestImpl ();  
4             TestProxy testProxy = new TestProxy (testImpl );  
5             testProxy.test();  
6       
7         }  
8     }  

2.Jdk动态代理

只能对实现了接口的类生产代理,不能针对类。

定义代理:

 1 public class MyInvocationHandler implements InvocationHandler {
 2         
 3         
 4         //目标对象
 5         private Object target;
 6         
 7         /**
 8          * 构造方法
 9          * @param target 目标对象
10          */
11         public MyInvocationHandler(Object target) {
12             super();
13             this.target=target;
14         }
15          
16          * 执行目标对象的方法 
17          */
18         public Object invoke(Object proxy, Method method, Object[] args)
19                 throws Throwable {
20             
21              //在目标方法执行前简单打印一下
22              System.out.println("----------before----------");
23              
24              //执行目标方法对象
25              Object result=method.invoke(target, args);
26              
27              //在目标方法执行之后简单打印一下
28              System.out.println("----------after----------");
29             
30              return result;
31         }
32         
33         
34         /**
35          * 获取目标对象的代理对象
36          * @return 代理对象
37          */
38         public Object getProxy(){
39             return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), 
40                     this.target.getClass().getInterfaces(),this);
41         }
42         
43 }

测试类:

 1 public class ProxyTest{
 2         
 3         @Test
 4         public void testProxy() throws Throwable{
 5             //实例化目标对象
 6             Test test=new TestImpl();
 7             
 8             //实例化Invocation
 9             MyInvocationHandler invocationHandler=new MyInvocationHandler(test);
10             
11             //根据目标生成代理对象
12             Test proxy=(Test)invocationHandler.getProxy();
13             
14             //调用代理对象方法
15             proxy.test();
16         }
17 }

3.cglib代理

cglib是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法,因为采用的是继承,所以不能对final修饰的类进行代理。

定义代理:

 1 public class CglibProxy implements MethodInterceptor {  
 2     private Object target;  
 3   
 4     /** 
 5      * 创建代理对象 
 6      *  
 7      * @param target 
 8      * @return 
 9      */  
10     public Object getInstance(Object target) {  
11         this.target = target;  
12         Enhancer enhancer = new Enhancer();  
13         enhancer.setSuperclass(this.target.getClass());  
14         // 回调方法  
15         enhancer.setCallback(this);  
16         // 创建代理对象  
17         return enhancer.create();  
18     }  
19   
20     @Override  
21     // 回调方法  
22     public Object intercept(Object obj, Method method, Object[] args,  
23             MethodProxy proxy) throws Throwable {  
24         System.out.println("事物开始");  
25         proxy.invokeSuper(obj, args);  
26         System.out.println("事物结束");  
27         return null;  
28   
29   
30     }  
31   
32 }  

测试类:

public class TestCglib {  
      
    public static void main(String[] args) {  
        CglibProxy cglib=new CglibProxy ();  
        Testmpl testImpl=(Testmpl)cglib.getInstance(new Testmpl());  
        testImpl.test();  
    }  

二 Spring Aop

AOP利用一种称为"横切"的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其命名为"Aspect",即切面。所谓"切面",简单说就是那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块之间的耦合度,并有利于未来的可操作性和可维护性。

使用"横切"技术,AOP把软件系统分为两个部分:核心关注点横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。横切关注点的一个特点是,他们经常发生在核心关注点的多处,而各处基本相似,比如权限认证、日志、事物。

Aop中的几个概念:

切面(Aspect) :官方的抽象定义为“一个关注点的模块化,这个关注点可能会横切多个对象”。
连接点(Joinpoint) :程序执行过程中的某一行为。
通知(Advice) :“切面”对于某个“连接点”所产生的动作。
切入点(Pointcut) :匹配连接点的断言,在AOP中通知和一个切入点表达式关联。
目标对象(Target Object) :被一个或者多个切面所通知的对象。
AOP代理(AOP Proxy) 在Spring AOP中有两种代理方式,JDK动态代理和CGLIB代理。

作用:

1、降低模块之间的耦合度

2、使系统容易扩展

3、更好的代码复用。

源码太多,就不一一列举了,源码分析可以参考:https://blog.csdn.net/hello_worldee/article/details/78136616

 






以上是关于Java代理及Spring AOP的主要内容,如果未能解决你的问题,请参考以下文章

Spring之AOP理解及使用

spring aop中this和target区别

Spring之AOP理解及使用

这一次搞懂Spring代理创建及AOP链式调用过程

Java——面向切面编程,Spring中的AOP编程

如何使用Proxy模式及Java内建的动态代理机制