【spring框架】AOP的Annotation实现(上)

来源:互联网 发布:SQL 重启计算机 编辑:程序博客网 时间:2024/04/29 03:52
使用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

需要加新的命名空间:
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@Componentpublic 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 {@Testpublic 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

0 0
原创粉丝点击