在进行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主要通过两种动态代理技术实现:JDK动态代理和CGLIB动态代理。 首先,让我们详细了解一下JDK动态代理。JDK动态代理基于Java的接口实现,它适用于目标对象实现了至少一个接口的情况。在运行时,JDK...
总的来说,Spring AOP 通过动态代理技术实现了切面的插入,使得我们可以对代码进行非侵入式的增强,提高了代码的复用性和可维护性。无论是 JDK 动态代理还是 CGLIB 动态代理,它们的核心都是在方法调用时插入额外的...
3. **反射机制**:在AOP动态代理中,反射机制扮演着重要角色。通过反射,我们可以动态获取类的信息,包括类的字段、方法等,并能够在运行时动态地调用方法。在创建代理对象和处理方法调用时,都会用到反射。 4. **...
动态代理则是Spring AOP实现的核心技术之一,它允许我们在运行时创建具有额外行为的对象。下面将详细阐述Spring AOP的配置以及动态代理的实现。 一、Spring AOP基础知识 1. **什么是AOP**:AOP是一种编程范式,...
总的来说,Spring AOP通过JDK动态代理提供了一种灵活的方式来实现横切关注点,使得业务代码更专注于核心功能,而无需关心日志、事务等通用逻辑。这极大地提高了代码的可读性和可维护性。在实际项目中,熟练掌握...
Spring框架是Java中实现AOP的一个流行工具,它通过动态代理机制实现了这一功能。本文将深入探讨Spring AOP的实现原理,以及如何使用反射来实现动态代理模式。 首先,我们需要了解AOP的基本概念。AOP的核心思想是切...
本篇文章将详细探讨如何通过Java的动态代理机制来模拟Spring AOP的核心概念。 首先,让我们了解什么是动态代理。在Java中,动态代理主要由`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口...
Spring AOP使用动态代理的方式实现方法织入,支持两种代理方式:基于JDK的动态代理和基于CGLIB的代理。JDK动态代理仅适用于接口的实现,而CGLIB代理则是通过创建目标类的子类来实现代理,因此可以代理任何类。 ...
5. AOP代理的使用:当通过Spring的依赖注入(DI)获取到一个对象时,实际上得到的是一个代理对象。通过这个代理对象调用方法,Spring会自动插入预先定义好的通知逻辑。 总的来说,JDK动态代理是Spring AOP实现的...
Spring AOP(Aspect Oriented Programming,面向切面编程)是Spring框架的重要组成部分,它提供了一种在不修改源代码的情况下,对程序进行功能增强的技术。这个"spring aop jar 包"包含了实现这一功能所需的类和接口,...
AnnotationAwareAspectJAutoProxyCreator类是Spring AOP用来创建代理对象的核心组件之一。它通过扫描类上标注了特定AOP注解的类(如@Aspect)并根据这些信息来创建代理对象。当容器中的bean需要创建时,...
5. **理解代理行为**:理解Spring AOP代理的工作方式很重要,因为这可能影响到何时以及如何调用通知。例如,直接通过`@Autowired`注入的bean之间的相互调用不会触发AOP通知,除非显式地通过代理引用进行调用。 6. *...
在这个例子中,我们将探讨如何使用动态代理来实现一个简单的Spring AOP功能。 动态代理是Java提供的一种机制,它允许我们在运行时创建对象的代理,该对象可以代表原对象执行额外的操作。在Spring AOP中,有两种主要...
1. **代理**:Spring AOP支持两种类型的代理:JDK动态代理和CGLIB代理。JDK代理用于实现了接口的类,而CGLIB代理则用于没有接口或不希望使用接口的类。代理对象在调用目标方法时会执行切面逻辑。 2. **织入**:织入...
Spring框架提供了两种动态代理机制:JDK动态代理和CGLIB代理,它们分别基于这两种技术。 1. JDK动态代理: - 当被代理的目标对象实现了至少一个接口时,Spring会选择使用JDK动态代理。它通过反射机制生成一个实现...
Spring框架是Java开发中不可或缺的一部分,它通过提供两种核心特性——控制反转(IoC)和面向切面编程(AOP)来简化应用的构建。理解并掌握这两种技术对于任何Java开发者来说都至关重要。 **控制反转(IoC)**,也...
同时,你也可以寻找与Spring AOP相关的配置或示例,了解如何定义切面、通知和切入点,以及如何在Spring上下文中启用AOP代理。 总之,动态代理和Spring AOP是Java开发中强大的工具,它们能帮助我们构建更灵活、可...
在Spring框架中,AOP(面向切面编程)是一种强大的工具,它允许程序员在不修改源代码的情况下,向应用程序添加跨切面的...理解和熟练运用AOP代理能够极大地提高代码的可维护性和复用性,是Spring开发者必备的技能之一。
Spring AOP代理是框架为实现切面功能创建的对象,它在运行时实现切面协议。Spring提供了两种代理方式:JDK动态代理和CGLIB代理。JDK代理适用于那些实现了接口的类,而CGLIB代理则适用于没有实现接口的类。 引介...