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

原文地址:https://www.cnblogs.com/jameszheng/p/10256680.html

时间: 2024-10-06 21:28:32

Java代理及Spring AOP的相关文章

java框架篇---spring AOP 实现原理

什么是AOP AOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善.OOP引入封装.继承和多态性等概念来建立一种对象层次结构,用以模拟公共行为的一个集合.当我们需要为分散的对象引入公共行为的时候,OOP则显得无能为力.也就是说,OOP允许你定义从上到下的关系,但并不适合定义从左到右的关系.例如日志功能.日志代码往往水平地散布在所有对象层次中,而与它所散布到的对象的核心功能毫无

jdk动态代理与cglib代理、spring aop代理实现原理解析

原创声明:本博客来源为本人原创作品,绝非他处摘取,转摘请联系博主 代理(proxy)的定义:为某对象提供代理服务,拥有操作代理对象的功能,在某些情况下,当客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用. 动态代理实现主要有2种形式,主要分为: 1.jdk动态代理: 1)原理:是根据类加载器和接口创建代理类(此代理类是接口的实现类,所以必须使用接口 面向接口生成代理,位于java.lang.reflect包下) 2)实现方式: 1. 通过实现Invocati

从动态代理到Spring AOP(上)

一.前言 虽然平时日常开发很少用到动态代理,但是动态代理在底层框架等有着非常重要的意义.比如Spring AOP使用cglib和JDK动态代理,Hibernate底层使用了javassit和cglib动态代理,Dubbo使用javassist字节码(具体可以看Dubbo SPI). 本文主要介绍什么是动态代理及原理,下文将介绍Spring AOP 我们先思考一个问题:如何统计一个类各个方法的执行时间?可能你心里有好多答案都可以解决问题. 那么如果是这个项目的多个不同类呢?可能心里也有答案,但是代

反射实现AOP动态代理模式(Spring AOP实现原理)

其实AOP的意思就是面向切面编程. OO注重的是我们解决问题的方法(封装成Method),而AOP注重的是许多解决问题的方法中的共同点,是对OO思想的一种补充! 还是拿人家经常举的一个例子讲解一下吧: 比如说,我们现在要开发的一个应用里面有很多的业务方法,但是,我们现在要对这个方法的执行做全面监控,或部分监控.也许我们就会在要一些方法前去加上一条日志记录. 我们写个例子看看我们最简单的解决方案 我们先写一个接口IHello.java代码如下: package sinosoft.dj.aop.st

java框架篇---spring aop两种配置方式

第一种:注解配置AOP 注解配置AOP(使用 AspectJ 类库实现的),大致分为三步: 1. 使用注解@Aspect来定义一个切面,在切面中定义切入点(@Pointcut),通知类型(@Before, @AfterReturning,@After,@AfterThrowing,@Around). 2. 开发需要被拦截的类. 3. 将切面配置到xml中,当然,我们也可以使用自动扫描Bean的方式.这样的话,那就交由Spring AoP容器管理. 另外需要引用 aspectJ 的 jar 包:

动态代理实现Spring Aop

引言 我们在前两篇文章中,都为这篇做了铺垫,我们现在来做这样一件事情,在业务逻辑中添加Aop的非业务逻辑. AopClinetTest: package com.tgb.client; import com.tgb.config.BeanFactory; import com.tgb.config.ClassPathXmlApplicationContext; import com.tgb.dao.UserDao; import com.tgb.domain.User; /** * AOP效果测

【设计模式】代理模式:静态代理,动态代理,spring aop

代理模式分为静态代理和动态代理.我们拿链家来举例子,我们本人是真实的对象,有真实的业务需求:需要去找房子:链家是中介,是代理类,他来帮我执行找房子的这个操作. 静态代理: 1.实现一个接口 public interface SearchHome { public void search(); } 2.构建实现接口的委托类 public class Master implements SearchHome { @Override public void search() { System.out.

Spring AOP中的动态代理

0  前言 1  动态代理 1.1 JDK动态代理 1.2 CGLIB动态代理 1.2.1 CGLIB的代理用法 1.2.2 CGLIB的过滤功能 2  Spring AOP中的动态代理机制 2.1 JdkDynamicAopProxy 2.2 CglibAopProxy 3 总结 0  前言 前一个季度旅游TDC的Thames服务有几次宕机,根据组内原因认真查找发现是数据库事务造成的,后来把服务中的事务配置全部去掉,服务恢复正常.根据这次教训,虽然现在还是很难确定是哪一个方面的真正原因,但是激

动态代理--Spring AOP分析

Spring AOP的基本实现方式 ?Spring AOP,一种模块化机制,可以动态的对切点增加行为,而不破坏原有的代码结构.这是一个很好地动态代理的应用方式,Spring AOP实现依赖于JDK的动态代理库和CGLIB字节码库技术两种来分别实现. ?在Spring AOP中,JdkDynamicAopProxy实现基于JDK动态代理生成代理对象,CglibAopProxy来实现基于CGLIB的动态代理对象生成.并通过DefaultAopProxyFactory进行调用,此处采用策略模式,针对不