`
一日一博
  • 浏览: 227087 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

Spring3核心技术之AOP动态代理

阅读更多
在进行AOP开发前,先熟悉几个概念
连接点(Jointpoint):表示需要在程序中插入横切关注点的扩展点,连接点可能是类初始化、方法执行、方法调用、字段调用或处理异常等等,Spring只支持方法执行连接点,在AOP中表示为“在哪里干”;
切入点(Pointcut):选择一组相关连接点的模式,即可以认为连接点的集合,Spring支持perl5正则表达式和AspectJ切入点模式,Spring默认使用AspectJ语法,在AOP中表示为“在哪里干的集合”;
通知(Advice):在连接点上执行的行为,通知提供了在AOP中需要在切入点所选择的连接点处进行扩展现有行为的手段;包括前置通知(before advice)、后置通知(after advice)、环绕通知(around advice),在Spring中通过代理模式实现AOP,并通过拦截器模式以环绕连接点的拦截器链织入通知;在AOP中表示为“干什么”;
方面/切面(Aspect):横切关注点的模块化,比如上边提到的日志组件。可以认为是通知、引入和切入点的组合;在Spring中可以使用Schema和@AspectJ方式进行组织实现;在AOP中表示为“在哪干和干什么集合”;
引入(inter-type declaration):也称为内部类型声明,为已有的类添加额外新的字段或方法,Spring允许引入新的接口(必须对应一个实现)到所有被代理对象(目标对象), 在AOP中表示为“干什么(引入什么)”;
目标对象(Target Object):需要被织入横切关注点的对象,即该对象是切入点选择的对象,需要被通知的对象,从而也可称为“被通知对象”;由于Spring AOP 通过代理模式实现,从而这个对象永远是被代理对象,在AOP中表示为“对谁干”;
AOP代理(AOP Proxy):AOP框架使用代理模式创建的对象,从而实现在连接点处插入通知(即应用切面),就是通过代理来对目标对象应用切面。在Spring中,AOP代理可以用JDK动态代理或CGLIB代理实现,而通过拦截器模型应用切面。
织入(Weaving):织入是一个过程,是将切面应用到目标对象从而创建出AOP代理对象的过程,织入可以在编译期、类装载期、运行期进行。

在AOP中,通过切入点选择目标对象的连接点,然后在目标对象的相应连接点处织入通知,而切入点和通知就是切面(横切关注点),而在目标对象连接点处应用切面的实现方式是通过AOP代理对象

AOP代理
AOP代理就是AOP框架通过代理模式创建的对象,Spring使用JDK动态代理或CGLIB代理来实现,Spring默认使用JDK动态代理来实现,但是只有实现接口的类的对象可被代理,如果被代理的对象实现不是接口将默认使用CGLIB代理,不过CGLIB代理当然也可应用到接口。

AOP代理的目的就是将切面织入到目标对象。

Spring AOP通过代理模式实现,目前支持两种代理:JDK动态代理、CGLIB代理来创建AOP代理,Spring建议优先使用JDK动态代理。要用到Spring AOP必须加入这些jar包:

JDK动态代理:使用java.lang.reflect.Proxy动态代理实现,即提取目标对象的接口,然后对接口创建AOP代理。
CGLIB代理:CGLIB代理不仅能进行接口代理,也能进行类代理,CGLIB代理需要注意以下问题:
       不能通知final方法,因为final方法不能被覆盖(CGLIB通过生成子类来创建代理)。
       会产生两次构造器调用,第一次是目标类的构造器调用,第二次是CGLIB生成的代理类的构造器调用。如果需要CGLIB代理方法,请确保两次构造器调用不影响应用。

Spring AOP默认首先使用JDK动态代理来代理目标对象,如果目标对象没有实现任何接口将使用CGLIB代理,如果需要强制使用CGLIB代理,请使用如下方式指定:
对于xml配置切面使用如下方式来指定使用CGLIB代理:

<aop:config proxy-target-class="true">  
</aop:config>

对于注解配置切面使用如下方式来指定使用CGLIB代理:
<aop:aspectj-autoproxy proxy-target-class="true"/>

下面来模拟一下JDK动态代理:
JDK动态代理首先要实现InvocationHandler接口,然后调用Proxy.newProxyInstance()静态方法返回目标对象的代理对象

/**
 * @author Chou
 * 创建动态代理对象有两种方法:
 * 1.像本类一样使用JDK的Proxy实现动态代理(需要目标对象的类必须有实现的接口)
 * 2.使用cglib这个jar包(目标对象的类不需要实现接口)
 * 注:Spring框架都用到了这两种方式,如果有实现接口,就第一种,没有实现就用第二种创建代理对象
 */
public class JDKProxyFactory implements InvocationHandler{
	
	private Object target;//需要代理的目标对象
	
	/**
	 * 通过Proxy.newProxyInstance()返回target这个对象的代理对象。
	 * 方法中需要target对象的类加载器target.getClass().getClassLoader()
	 * 还有target对象实现的所有的接口,target.getClass().getInterfaces()
	 * 既然target实现了这么多接口,那么返回的target的代理对象肯定也要实现这些接口
	 * this这个对象必须是实现了InvocationHandler接口的对象
	 */
	public Object createProxyIntance(Object target) {//target需要代理的对象
		this.target = target;
		return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
	}
	
	
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		Interceptor.prepareDomain();//加入的拦截方法
		return method.invoke(target, args);
	}

}

public class MyBeanB implements MyBean{
	public void domain() {
		System.out.println("MyBeanB is executing...");
	}
}

//拦截方法
public class Interceptor {
	public static void prepareDomain() {
		System.out.println("This is prepareDomain....");
	}
}

//main方法....
JDKProxyFactory aop = new JDKProxyFactory();
String[] configs = new String[] {"applicationContext.xml"};
ApplicationContext cxt = new ClassPathXmlApplicationContext(configs);
MyBean proxyObj = (MyBean)aop.createProxyIntance(cxt.getBean("beanB",MyBeanB.class));
proxyObj.domain();

下面来模拟一下CGLIB动态代理:
这种代理目标对象的方式必须加入CGlib的jar包,并且实现MethodInterceptor接口

public class CGlibProxyFactory implements MethodInterceptor{
	
	private Object target;//需要代理的目标对象
	
	public Object createProxyIntance(Object target) {
		this.target = target;
		Enhancer enhancer = new Enhancer();
		enhancer.setSuperclass(this.target.getClass());
		enhancer.setCallback(this);
		return enhancer.create();
	}

	@Override
	public Object intercept(Object object, Method method, Object[] args,
			MethodProxy methodProxy) throws Throwable {
		Interceptor.prepareDomain();
		return method.invoke(target, args);
	}
}

public class MyBeanB{
	public void domain() {
		System.out.println("MyBeanB is executing...");
	}
}

//main方法...
String[] configs = new String[] {"applicationContext.xml"};
ApplicationContext cxt = new ClassPathXmlApplicationContext(configs);
CGlibProxyFactory aop = new CGlibProxyFactory();
MyBeanB proxyObj = (MyBeanB) aop.createProxyIntance(cxt.getBean("beanB",MyBeanB.class));
proxyObj.domain();

在spring中获取代理对象代理的目标对象工具类:
http://jinnianshilongnian.iteye.com/blog/1613222
  • 大小: 28.2 KB
分享到:
评论

相关推荐

    Spring AOP源码深度解析:掌握Java高级编程核心技术

    Spring AOP是基于代理模式实现的,主要包括动态代理、通知(Advice)、切点(Pointcut)、切面(Aspect)和连接点(Join point)。动态代理是实现AOP的基础,它通过JDK动态代理或CGLIB代理生成被代理对象的子类。...

    Spring AOP核心编程思想教程

    非常详细的介绍Spring AOP全栈技术点,开篇帮助同学们进行知识储备,...从Spring AOP概念开始引入,通过Spring AOP代理和判断模式进行,宝库各种模式,不断的深入学习,相信会给同学们带来不一样的Spring AOP技术体验。

    进击的编程思想!带你学Spring AOP核心编程思想教程 新角度学面向切面编程

    何谓Spring AOP? Spring AOP 是基于 AOP 编程模式的一个框架,它的...课程从Spring AOP概念开始引入,通过Spring AOP代理和判断模式进行,宝库各种模式,不断的深入学习,相信会给同学们带来不一样的Spring AOP技术

    spring-aop.zip

    Spring以JVM的动态代理技术为基础,设计出了一系列的AOP横切实现,比如前置通知、返回通知、异常通知等。同时,Pointcut接口可以匹配切入点,可以使用现有的切入点来设计横切面,也可以扩展相关方法根据需求进行切入...

    spring第五天 .pdf

    3. 认识Spring AOP中底层常用的一些核心类 4. 源码阅读之查找aop相关的BeanDefinitionParser流程 5. 源码阅读之查找aop相关的BeanDefinitionParser的执行流程 6. 源码阅读之产生AOP代理对象的流程 7. 代理对象执行流...

    spring_aop_cglib的实现方式

    如果想使用CGLIB的技术来生成代理对象,那么需要引入CGLIB的开发的jar包,在Spring框架核心包中已经引入了CGLIB的开发包了。所以直接引入Spring核心开发包即可!

    深入解析Spring AOP源码:从原理到实现,全方位掌握Java AOP编程精髓

    Spring AOP主要基于动态代理模式,它允许开发者在不改变原有代码结构的情况下,增加额外的行为。这主要通过定义“切面(Aspects)”和“通知(Advices)”来实现,其中切面定义了何时以及如何插入额外的行为,而通知...

    springboot2-spring5-studying:Springboot2,Spring源码学习项目,涉及SpringBoot2自动装配实现机制,Spring AOP动态代理以及IOC各种扩展接口的实现方式

    Spring AOP多种代理机制相关核心类介绍先介绍一些Spring Aop中一些核心类,大致分为三类: advisorCreator ,从spring ioc的扩展接口beanPostProcessor继承,主要用作扫描获取advisor。 advisor :顾问的意思,封装...

    spring第四天.pdf

    7. 重点掌握aop底层的原理之动态代理机制的概述及差别 8. 重点掌握JDK代理技术之产生代理对象和代理对象执行逻辑分析 9. 重点掌握Cglib代理技术之产生代理对象和代理对象执行逻辑分析 10. 认识Spring AOP中底层常用...

    spring4.1核心包

    6. spring-core-4.1.1.RELEASE.jar spring核心包 7. spring-expression-4.1.1.RELEASE.jar spring表达语言 SpEL以"#{...}"进行标识。 8. spring-instrument-4.1.1.RELEASE.jar Spring对服务器的代理接口 9.spring-...

    java AOP aspectjrt-1.8.14 AOP核心大集合

    spring-aop:AOP核心功能,例如代理工厂等等aspectjweaver:简单理解,支持切入点表达式等等aspectjrt:简单理解,支持aop相关注解等等

    Spring官网阅读(十八)Spring中的AOP

    这里写目录标题什么是AOPAOP中的核心概念切面通知切点引入目标对象代理对象织入Spring中如何使用AOP1、开启AOP2、申明切面3、申明切点切点表达式excecution表达式语法示例@annotation表达式语法示例within表达式语法...

    Spring攻略PDF版

     第5章 动态代理和经典的Spring AOP   第6章 Spring 2.x AOP和AspectJ支持  第二部分 基础主题  第7章 Spring对JDBC的支持   第8章 Spring中的事务管理   第9章 Spring对ORM的支持   第10章...

    Spring攻略中文版PDF

     第5章 动态代理和经典的Spring AOP   第6章 Spring 2.x AOP和AspectJ支持  第二部分 基础主题  第7章 Spring对JDBC的支持   第8章 Spring中的事务管理   第9章 Spring对ORM的支持   第10章...

    Spring高级之注解驱动开发视频教程

    Spring本身里面包含了两大核心IOC和AOP。IOC负责降低我们代码间的依赖关系,使我们的项目灵活度更高,可复用性更强。AOP是让方法间的各个部分更加独立,达到统一调用执行,使后期维护更加的方便。 SpringMVC本身是...

    吴天雄--Spring笔记.doc

    第二天内容:AOP(AOP常用概念、Spring的三种aop实现方式、代理设计模式(静态代理和动态代理));第三天内容:Spring自动装配,Spring自动加载properties文件,单例设计模式,声明式事务,Ajax,JSON。 --author:

    Spring攻略英文版(附带源码)

     第5章 动态代理和经典的Spring AOP   第6章 Spring 2.x AOP和AspectJ支持  第二部分 基础主题  第7章 Spring对JDBC的支持   第8章 Spring中的事务管理   第9章 Spring对ORM的支持   第10章 ...

    spring第三天.pdf

    3. 可以自主完成阅读Spring框架中依赖注入流程的源码 4. 可以确定aop流程的源码阅读入口 5. 搞清楚aop相关的核心概念(通知、切面、切入点等) 6. 搞清楚cglib和jdk动态代理的区别 7. 掌握cglib和jdk产生代理对象的...

    Java Framework 关于IOC、AOP、Log的案例源码

    Spring整体框架中的核心功能,例如:IOC、AOP、Bean生命周期、上下文、作用域、资源处理等内容在本源码中都有实现。 适合人群:具备一定编程基础,工作1-3年的研发人员 能学到什么:IOC、AOP、代理、切面等都是如何...

    Spring内容讲解与介绍

    Spring框架的核心技术是IOC和AOP(采用jdk和cglib动态代理实现的)

Global site tag (gtag.js) - Google Analytics