使用Annotation来实现AOP的动态代理:
@AspectJ支持
@AspectJ使用了Java 5的注解,可以将切面声明为普通的Java类。@AspectJ样式在AspectJ 5发布的AspectJ project部分中被引入。Spring 2.0使用了和AspectJ 5一样的注解,并使用AspectJ来做切入点解析和匹配。但是,AOP在运行时仍旧是纯的Spring AOP,并不依赖于AspectJ的编译器或者织入器(weaver)。
使用AspectJ的编译器或者织入器的话就可以使用完整的AspectJ语言,我们将在第 6.8 节 “在Spring应用中使用AspectJ”中讨论这个问题。
6.2.1. 启用@AspectJ支持
为了在Spring配置中使用@AspectJ切面,你首先必须启用Spring对@AspectJ切面配置的支持,并确保自动代理(autoproxying)的bean是否能被这些切面通知。自动代理是指Spring会判断一个bean是否使用了一个或多个切面通知,并据此自动生成相应的代理以拦截其方法调用,并且确保通知在需要时执行。
通过在你的Spring的配置中引入下列元素来启用Spring对@AspectJ的支持:
<aop:aspectj-autoproxy/>
需要的jar包:aspectjrt.jar、aspectjweaver.jar
需要加新的命名空间:
beans.xml:
实验:
需要加在前面的代理类LogInterceptor:
测试:
method start
add success!!
原理:
首先spring会通过
execution可以指定在任何方法上,UserDaoImpl自己的业务逻辑不会受任何影响,它甚至不知道有新的逻辑切入进来了,这就保证了UserDaoImpl业务逻辑的纯洁性。
下面介绍一些专业术语:
关于Spring的AOP的一些专业术语:
1.JoinPoint:
连接点、切入点
就是说在哪些点上把切面逻辑加进去(比如在save方法之前)
2.PointCut:
切入点的集合
我们可以一下定好多切入点
例如:在com.xyz.someapp.service任何类的任何方法切入
@PointCut("execution(* com.xyz.someapp.service.*.*(...))")
public voidbussinessService(){}
3.Aspect(切面):
前面我们写的LogInterceptor切面类里面有好多方法加到不同的被代理的对
象上面去,这就是那个切面。也就是加@Aspect注解的类。
4.Advice:
在加入的那个点上的"建议",与Aspect意思有些重合。
可以这样理解,Aspect是个"面",而Advice是那个"面"的逻辑
就是在你要代理的方法上加"@Before或@After等逻辑"
5.Target:
被代理对象
把我们的业务逻辑"织入"到哪个对象上面去
6.Weave:
织入。
@AspectJ支持
@AspectJ使用了Java 5的注解,可以将切面声明为普通的Java类。@AspectJ样式在AspectJ 5发布的AspectJ project部分中被引入。Spring 2.0使用了和AspectJ 5一样的注解,并使用AspectJ来做切入点解析和匹配。但是,AOP在运行时仍旧是纯的Spring AOP,并不依赖于AspectJ的编译器或者织入器(weaver)。
使用AspectJ的编译器或者织入器的话就可以使用完整的AspectJ语言,我们将在第 6.8 节 “在Spring应用中使用AspectJ”中讨论这个问题。
6.2.1. 启用@AspectJ支持
为了在Spring配置中使用@AspectJ切面,你首先必须启用Spring对@AspectJ切面配置的支持,并确保自动代理(autoproxying)的bean是否能被这些切面通知。自动代理是指Spring会判断一个bean是否使用了一个或多个切面通知,并据此自动生成相应的代理以拦截其方法调用,并且确保通知在需要时执行。
通过在你的Spring的配置中引入下列元素来启用Spring对@AspectJ的支持:
<aop:aspectj-autoproxy/>
需要的jar包:aspectjrt.jar、aspectjweaver.jar
需要加新的命名空间:
xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"
beans.xml:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"> <context:annotation-config/> <context:component-scan base-package="cn.edu.hpu"/> <!-- 可以采用使用aspectj注解的方式产生aop --> <aop:aspectj-autoproxy/><!-- 自动产生代理,原理是aspectj,它是一个专门用来生成代理的框架 --> </beans>
实验:
需要加在前面的代理类LogInterceptor:
package cn.edu.hpu.aop; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.springframework.stereotype.Component; @Aspect @Component public class LogInterceptor { //在方法执行之前先执行这个方法 //execution是织入点语法 @Before("execution(public void cn.edu.hpu.dao.Impl.UserDaoImpl.save(cn.edu.hpu.model.User))") public void before(){ System.out.println("method start"); } }
测试:
package cn.edu.hpu.service; import org.junit.Test; import org.springframework.beans.factory.BeanFactory; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import cn.edu.hpu.dao.UserDao; import cn.edu.hpu.model.User; public class UserServiceTest { @Test public void testAdd() throws Exception{ ClassPathXmlApplicationContext ctx=new ClassPathXmlApplicationContext("beans.xml"); UserService userService=(UserService)ctx.getBean("userService"); User u=new User(); u.setUsername("u1"); u.setPassword("p1"); userService.add(u); ctx.destroy(); } }结果:
method start
add success!!
原理:
首先spring会通过
<context:annotation-config/> <context:component-scan base-package="cn.edu.hpu"/>去按照注解@Component注解去找相应的bean,在找LogInterceptor的时候,它发现这个类还是一个@Aspect,也就是说这个是个切面逻辑,可以把它切到其它的方法上面去,那么它怎么往里切呢?他发现了你用@Before定义了一下,在这个execution指定的方法执行之前(execution方法、属性、类)去执行下面定义的方法。
execution可以指定在任何方法上,UserDaoImpl自己的业务逻辑不会受任何影响,它甚至不知道有新的逻辑切入进来了,这就保证了UserDaoImpl业务逻辑的纯洁性。
下面介绍一些专业术语:
关于Spring的AOP的一些专业术语:
1.JoinPoint:
连接点、切入点
就是说在哪些点上把切面逻辑加进去(比如在save方法之前)
2.PointCut:
切入点的集合
我们可以一下定好多切入点
例如:在com.xyz.someapp.service任何类的任何方法切入
@PointCut("execution(* com.xyz.someapp.service.*.*(...))")
public voidbussinessService(){}
3.Aspect(切面):
前面我们写的LogInterceptor切面类里面有好多方法加到不同的被代理的对
象上面去,这就是那个切面。也就是加@Aspect注解的类。
4.Advice:
在加入的那个点上的"建议",与Aspect意思有些重合。
可以这样理解,Aspect是个"面",而Advice是那个"面"的逻辑
就是在你要代理的方法上加"@Before或@After等逻辑"
5.Target:
被代理对象
把我们的业务逻辑"织入"到哪个对象上面去
6.Weave:
织入。
和织布机一样,横排的织完,竖排的再去织,这时候就像业务逻辑切进去一样,被织入进去了。
转载请注明出处:http://blog.csdn.net/acmman/article/details/44344193