@AspectJ配置切面
编程方式实现
public class Waiter {
public void check(String name){
System.out.println("waiter说:结账?"+name);
}
public void serve(String name){
System.out.println("waiter说:要点什么?"+name);
}
}
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
public class PreGreeting {
@Before("execution(* serve(..))")
public void beforeGreeting(){
System.out.println("how are you!");
}
}
@Before注解表示前置增强,后面的切点表达式表示在目标类的serve()方法织入增强,serve()方法可以带任意的传入参数和任意的返回值。
PreGreeting类通过注解,将切点,增强类型和增强的横切逻辑组合在一起。PreGreeting类相当于上一篇中的BeforeAdvice(增强)
,NameMatchMethodPointcut(切点)
,DefaultPointcutAdvisor(切面)
三者联合表达的信息。
Waiter waiter=new Waiter();
AspectJProxyFactory factory=new AspectJProxyFactory();
factory.setTarget(waiter);//设置目标类
factory.addAspect(PreGreeting.class);//添加切面
Waiter proxy=factory.getProxy();
proxy.serve("TheViper");
proxy.check("TheViper");
how are you!
waiter说:要点什么?TheViper
waiter说:结账?TheViper
通过配置使用
<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"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<aop:aspectj-autoproxy/>
<bean id='waiter' class='aspectj.Waiter'/>
<bean class='aspectj.PreGreeting'/>
</beans>
引用aop命名空间
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="...
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd"
<aop:aspectj-autoproxy/>
自动为spring容器中那些匹配@AspectJ切面的Bean创建代理,完成切面织入
ApplicationContext ctx=new ClassPathXmlApplicationContext("beans.xml");
Waiter waiter=(Waiter)ctx.getBean("waiter");
waiter.serve("TheViper");
waiter.check("TheViper");
使用的时候,直接获取bean操作就可以了,不用像前面还要创建AspectJProxyFactory,设置好代理才能用。
schema配置切面
配置命名切点
需要引入aspectjweaver
public class GreetBefore {
public void say(String name){
System.out.println("hallo!"+name);
}
}
增强不用像上一篇中那样,需要继承特定类或实现特定接口。
<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"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id='waiterTarget' class='com.Waiter'/>
<bean id='greetBefore' class='schema.GreetBefore'/>
<aop:config>
<aop:pointcut expression="target(com.Waiter) and execution(* check(..)) and args(name,..)"
id="servePointcut"/>
<aop:aspect ref="greetBefore">
<aop:before method="say" pointcut-ref="servePointcut"/>
</aop:aspect>
</aop:config>
</beans>
匹配Waiter类中的check()方法。
需要引入
aop命名空间
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="... http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd"
<aop:aspect>
定义切面,其内部可以定义多个增强,ref属性指定引用的具体增强<aop:before>
声明了一个前置增强,通过pointcut-ref属性引用切点,method属性指定增强中哪个方法用于具体的增强行为<aop:pointcut>
定义切点,expression属性设置切点表达式,其语法和@AspectJ中的语法完全相同。
public class Waiter {
public void check(String name){
System.out.println("waiter说:结账?"+name);
}
public void serve(String name){
System.out.println("waiter说:要点什么?"+name);
}
}
ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
Waiter waiter=(Waiter)ctx.getBean("waiterTarget");
waiter.serve("TheViper");
waiter.check("TheViper");
waiter说:要点什么?TheViper
hallo!TheViper
waiter说:结账?TheViper
配置顺序问题
命名切点只能被当前<aop:aspect>内定义的元素访问到,<aop:config>中的配置顺序必须是<aop:pointcut>=><aop:advisor>=><aop:aspect>
各种增强类型
后置增强
<aop:config>
...
<aop:aspect ref="greetBefore">
<aop:after-returning method="sayEnjoy" pointcut='target(com.Waiter) and execution(* serve(..))'/>
</aop:aspect>
</aop:config>
环绕增强
<aop:config>
...
<aop:aspect ref="greetBefore">
<aop:around method="aroundMethod" pointcut='execution(* serve(..)) and within(com.Waiter))'/>
</aop:aspect>
</aop:config>
public void aroundMethod(ProceedingJoinPoint pjp){
//pjp可以访问到环绕增强的连接点信息
...
}
抛出异常增强
<aop:config>
...
<aop:aspect ref="greetBefore">
<aop:after-throwing method="afterThrowingMethod" pointcut='target(com.Waiter) and
execution(* serve(..))' throwing='exception'/>
</aop:aspect>
</aop:config>
public void afterThrowingMethod(Exception exception){
...
}
throwing属性声明需要绑定的异常对象,指定的异常名必须和增强方法对应的传入参数一致
final增强
<aop:config>
...
<aop:aspect ref="greetBefore">
<aop:after method="afterMethod" pointcut='execution(*com.Waiter. serve(..))'/>
</aop:aspect>
</aop:config>
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。