Spring-AOP小结

基础性的知识点,参考:http://www.docin.com/p-650303600.html

什么是AOP

Aspect Oriented Programming 面向方面/切面编程


AOP的作用

实现组件的重复利用,将共通组件与目标对象解耦,改善程序结构,提高灵活性


相关概念

1.Aspect切面
2.JoinPoint连接点:切面组件在目标对象上作用的位置
3.Pointcut切入点:连接点的集合,采用表达式指定
4.Target Object目标对象
5.Advice通知:切面组件在连接点上执行的动作,如:方法调用前/后/前后
6.AutoProxy动态代理:采用AOP之后,容器返回代理对象,用户使用后,由代理对象调用切面组件和目标对象的功能
a.目标对象有接口采用JDK代理 b没有接口采用CGLIB代理


使用

1.引入Jar包

所需Jar包

aspectjrt.jar  aspectjweaver.jar 
结合spring框架所需jar
        <dependency>
            <groupId>aopalliance</groupId>
            <artifactId>aopalliance</artifactId>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
        </dependency>
 
       
2.新建切面
切面只是普通的bean
例如:
public class OptLogger{
	//前置方法
	public void logger(){
		System.out.println("记录日志");
	}
	
	//后置方法
	public void myafterReturing(Object retVal){
	   System.out.println("后置通知"+retVal);
	}
	
	//异常方法
	public void myafterException(Exception ex){
	   System.out.println("--异常通知begin--");
	   ex.printStackTrace();
	   System.out.println("--异常通知end--");
	}
	
	//最终通知
	public void myafter(){
		System.out.println("--最终通知--");
	}
}
 
3.配置文件
<!--注册切面-->
<bean id = "optLogger" class="tarena.aop.OptLogger"></bean>

<aop:config>
	<aop:pointcut id="servicepointcut" expression="execution(* tarena.service.*.*(..))" />
	<!--前置通知-->
	<aop:aspect id="loggeraspect" ref="optLogger">
		<aop:before method="logger" pointcut-ref="servicepointcut"/>
	</aop:aspect>
	<!--后置通知-->
	<aop:aspect id="loggeraspect" ref="optLogger">
		<aop:after-returing method="myafterReturing" return="retVal" pointcut-ref="servicepointcut"/>
	</aop:aspect>
	<!--异常通知-->	
	<aop:aspect id="loggeraspect" ref="optLogger">
		<aop:after-thowing method="myafterException" throwing="ex" pointcut-ref="servicepointcut"/>
	</aop:aspect>	
	<!--最终通知 不论是否发生异常都会执行-->	
	<aop:aspect id="loggeraspect" ref="optLogger">
		<aop:after method="myafter" pointcut-ref="servicepointcut"/>
	</aop:aspect>	
	
</aop:config>
  4.切入点表达式说明:
Pointcut可以有下列方式来定义或者通过&& || 和!的方式进行组合.
args()
@args()
execution()
this()
target()
@target()
within()
@within()
@annotation
其中:其中execution 是用的最多的,其格式为:
execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern)throws-pattern?)
returning type pattern,name pattern, and parameters pattern是必须的.
ret-type-pattern
1.*表示任何返回值
2.全路径的类名等.
 
name-pattern:指定方法名 parameters pattern:指定方法参数(声明的类型)
1.(..)代表所有参数
2.(*)代表一个参数
3.(*,String)代表第一个参数为任何值,第二个为String类型.
具体举例说明:
任意公共方法的执行: execution(public * *(..))
任何一个以“set”开始的方法的执行: execution(* set*(..))
AccountService 接口的任意方法的执行:execution(* com.xyz.service.AccountService.*(..))
定义在service包里的任意方法的执行:execution(* com.xyz.service.*.*(..))
定义在service包和所有子包里的任意类的任意方法的执行:execution(* com.xyz.service..*.*(..))
定义在pointcutexp包和所有子包里的JoinPointObjP2类的任意方法的执行: execution(* com.test.spring.aop.pointcutexp..JoinPointObjP2.*(..))")
*** >  最靠近(..)的为方法名, 靠近.*(..))的为类名或者接口名,如上例的JoinPointObjP2.*(..))

pointcutexp包里的任意类.
within(com.test.spring.aop.pointcutexp.*)
pointcutexp包和所有子包里的任意类.
within(com.test.spring.aop.pointcutexp..*)
实现了Intf接口的所有类,如果Intf不是接口,限定Intf单个类.
this(com.test.spring.aop.pointcutexp.Intf)
***> 当一个实现了接口的类被AOP的时候,用getBean方法必须cast为接口类型,不能为该类的类型.

带有@Transactional标注的所有类的任意方法.
@within(org.springframework.transaction.annotation.Transactional)
@target(org.springframework.transaction.annotation.Transactional)
带有@Transactional标注的任意方法.
@annotation(org.springframework.transaction.annotation.Transactional)
***> @within和@target针对类的注解,@annotation是针对方法的注解

参数带有@Transactional标注的方法.
@args(org.springframework.transaction.annotation.Transactional)
参数为String类型(运行是决定)的方法.
args(String)
Pointcut 可以通过Java注解和XML两种方式配置,如下所示: -- 待补








猜你喜欢

转载自zjjndnr.iteye.com/blog/2389310