对于spring使用aop,为了实现不将横切逻辑织入到目标类的所有方法中去,从而要使用切点来定位某个类的某个方法.但有仅有切点无法实现AOP,因为还需要横切逻辑(平时所说的通知),切面就可以包含这些信息.创建切面的方法有很多种,但使用基于@AspectJ方式的配置应是最简单的.
1.将目标类注册成Bean
2.注册切面类(包含了切点,横切逻辑)
3.注册自动代理创建器(用来解析带有@Aspect注解的类)
关于切点表达式(有点复杂):
1.函数
A.方法切点:a.execution()表示满足某一匹配模式的所有目标类方法连接点;b.@annotation()表示标注了特定注解的目标方法连接点.
B.方法入参:a.args()判别目标类方法运行时入参对象的类型定义指义指定连接点;@args()表示是否标注特定注解来指定连接点.
C.目标类切点:a.within()表示特定域下的所有连接点;b.@within();c.target()假如目标类按类型匹配于指定类,则目标类的所有连接点匹配这个切点;d.@target();
D.代理类切点:this()
2.通配符
*匹配任意字符,但只匹配上下文中的一个元素.
..匹配任意字符,可以匹配上下文中的多个元素.表示类时,要与*联合使用;表示入参时,单独使用;
+表示按类型匹配指定类的所有类,必须跟在类名后面.
注意点:
a.支持所有通配符:execution(),within()
b.仅支持+通配符:args(),target(),this()
c.不支持通配符:@args(),@within(),@target(),@annotation()
切点函数间还可以进行逻辑运算,&&与,||或,!非
1.将目标类注册成Bean
2.注册切面类(包含了切点,横切逻辑)
3.注册自动代理创建器(用来解析带有@Aspect注解的类)
spring配置applicationContext.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<bean id="forumServiceImpl" class="org.exam.aop.ForumServiceImpl" />
<bean id="forumServiceAspect" class="org.exam.aop.ForumServiceAspect" />
<bean id="annotationAwareAspectJAutoProxyCreator" class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator" />
</beans>
其中ForumServiceImpl不必实现ForumService接口,annotationAwareAspectJAutoProxyCreator是自动代理创建器,ForumServiceAspect内容如下:
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
public class ForumServiceAspect {
@Before("execution(* removeTopic(..))")
public void beforeRemoveTopic(){
System.out.println("beforeRemoveTopic");
}
}
可以使用<aop:aspectj-autoproxy />来解析@Aspect类.它内部实质上还是用到了AnnotationAwareAspectJAutoProxyCreator.
<?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.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<aop:aspectj-autoproxy />
<bean id="forumServiceImpl" class="org.exam.aop.ForumServiceImpl" />
<bean id="forumServiceAspect" class="org.exam.aop.ForumServiceAspect" />
</beans>
如果使用java-config方式的spring配置,使用@EnableAspectJAutoProxy相当于<aop:aspectj-autoproxy />
关于切点表达式(有点复杂):
1.函数
A.方法切点:a.execution()表示满足某一匹配模式的所有目标类方法连接点;b.@annotation()表示标注了特定注解的目标方法连接点.
B.方法入参:a.args()判别目标类方法运行时入参对象的类型定义指义指定连接点;@args()表示是否标注特定注解来指定连接点.
C.目标类切点:a.within()表示特定域下的所有连接点;b.@within();c.target()假如目标类按类型匹配于指定类,则目标类的所有连接点匹配这个切点;d.@target();
D.代理类切点:this()
2.通配符
*匹配任意字符,但只匹配上下文中的一个元素.
..匹配任意字符,可以匹配上下文中的多个元素.表示类时,要与*联合使用;表示入参时,单独使用;
+表示按类型匹配指定类的所有类,必须跟在类名后面.
注意点:
a.支持所有通配符:execution(),within()
b.仅支持+通配符:args(),target(),this()
c.不支持通配符:@args(),@within(),@target(),@annotation()
切点函数间还可以进行逻辑运算,&&与,||或,!非