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

使用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
@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

你可能感兴趣的:(spring,动态代理,AOP,面向切面)