开始聊聊注解!
Spring切面可以应用5种类型的通知:
1 Before---在方法被调用之前调用通知
2 After--- 在方法完成之后调用通知,无论方法执行是否成功
3 After-returning---在方法成功执行之后调用通知!
4 After-throwing---在方法抛出异常后调用通知
5 Around---通知包裹了被通知的方法,在被通知的方法调用之前和调用之后执行自定义的行为。
在目标对象的生命周期里有多个点可以进行织入
1 编译期---切面在目标类编译时被织入,这种方式需要特殊的编译器,AspectJ的织入编译器就是以这种方式植入切面的。
2 类加载期---切面在目标类加载到JVM时被植入,这种方式需要特殊的类加载器,可以在目标类被引入应用之前增强该目标类的字节码。
AspectJ5的LTW就支持以这种方式植入切面。
3 运行期---切面在应用运行的某个时刻被植入,一般情况下,在植入切面时,AOP容器会为目标对象动态的创建一个代理对象。
Spring AOP就是以这种方式植入切面的。
Spring提供了4种各具特色的AOP支持:
1基于代理的经典AOP
2@AspectJ注解驱动的切面
3纯POJO切面
4注入式ASPECTJ切面
Spring借助AspectJ的切点表达式语言来定义Spring切面
arg() 限制连接点匹配参数为指定类型的执行方法
@args() 限制连接点匹配参数由指定注解标注的执行方法
execution()用于匹配是连接点的执行方法
this()限制连接点匹配AOP代理的bean引用为指定类型的类
target()限制连接点匹配目标对象为指定类型的类
@target()限制连接点匹配特定的执行对象,这些对象对应的类要具备指定类型的注解
within()限制连接点匹配指定的类型
@within()限制连接点匹配指定注解所标注的类型(当使用spring AOP时,方法定义在由指定的注解所标注的类里)
@annotation 限制匹配带有指定注解连接点
================================
execution( * <!--返回任意类型--> com.a.b.c.method(..)) 后面表示任意参数
表示触发条件!
---
execution( * <!--返回任意类型--> com.a.b.c.method(..)) 后面表示任意参数
&& within(a.b.c.*)这个是指包下面的任意类的方法被调用时
||表示或,!表示非
如果加上and bean(beanId)则表示必须是这个bean上执行。
!bean(id)不解释
---
<aop:advisor> 定义AOP通知器
<aop:after>定义AOP后置通知(不管被通知的方法是否执行成功)
<aop:after-returning>定义AOP after-returning通知
<aop:after-throwing>定义after-throwing通知
<aop:around>定义AOP环绕通知
<aop:aspect>定义切面
<aop:aspectj-autoproxy>启动@AspectJ注解驱动的切面
<aop:before>定义AOP前置通知
<aop:config>顶层的AOP配置元素,大多数的<aop:*>元素必须包含在<aop:config>元素内
<aop:declare-parents>为被通知的对象引入额外的接口,并透明的实现
<aop:pointcut>定义切点
----------------------------------------
package com.springinaction.springidol;
public class Audience {
public void takeSeats(){
System.out.println("The audience is taking their seats.");
}
public void turnOffCellPhones(){
System.out.println("The audience is turning off their cellphones.");
}
public void applaud(){
System.out.println("CLAP CLAP CLAP");
}
public void demandRefund(){
System.out.println("Boo! we want our money back!");
}
}
对应的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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="audience" class="com.springinaction.springidol.Audience" />
<aop:config>
<aop:aspect ref="audience">
<aop:before pointcut="execution(* com.springinaction.springidol.Performer.perform(..))"
method="takeSeats" />
<aop:before pointcut="execution(* com.springinaction.springidol.Performer.perform(..))"
method="turnOffCellPhones" />
<aop:after-returning pointcut="execution(* com.springinaction.springidol.Performer.perform(..))"
method="applaud" />
<aop:after-throwing pointcut="execution(* com.springinaction.springidol.Performer.perform(..))"
method="demandRefund" />
</aop:aspect>
</aop:config>
</beans>
或者这么写
<aop:config>
<aop:aspect ref="audience">
<aop:pointcut id="performance" expression="execution(* com.springinaction.springidol.Performer.perform(..))"/>
<aop:before pointcut-ref="performance" method="takeSeats" />
<aop:before pointcut-ref="performance" method="turnOffCellPhones" />
<aop:after-returning pointcut-ref="performance" method="applaud" />
<aop:after-throwing pointcut-ref="performance" method="demandRefund" />
</aop:aspect>
</aop:config>
----------------------以下为真实可运行版本
package com.springinaction.springidol;
public class Audience {
public void takeSeats(){
System.out.println("The audience is taking their seats.");
}
public void turnOffCellPhones(){
System.out.println("The audience is turning off their cellphones.");
}
public void applaud(){
System.out.println("CLAP CLAP CLAP");
}
public void demandRefund(){
System.out.println("Boo! we want our money back!");
}
}
package com.springinaction.springidol;
public class Performer {
public void perform(){
System.out.println("actors perform...");
}
}
<?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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<bean id="performer" class="com.springinaction.springidol.Performer" />
<bean id="audience" class="com.springinaction.springidol.Audience" />
<aop:config>
<aop:aspect ref="audience">
<aop:before pointcut="execution(* com.springinaction.springidol.Performer.perform(..))"
method="takeSeats" />
<aop:before pointcut="execution(* com.springinaction.springidol.Performer.perform(..))"
method="turnOffCellPhones" />
<aop:after-returning pointcut="execution(* com.springinaction.springidol.Performer.perform(..))"
method="applaud" />
<aop:after-throwing pointcut="execution(* com.springinaction.springidol.Performer.perform(..))"
method="demandRefund" />
</aop:aspect>
</aop:config>
</beans>
package com.springinaction.springidol;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class test {
public static void main(String[] args){
ApplicationContext appContext = new ClassPathXmlApplicationContext("t.xml");
Performer p= appContext.getBean("performer", Performer.class);
p.perform();
}
}