<span style="font-size:18px;">1、@AspectJ形式的Spring AOP
@AspectJ代表一种定义Aspect的风格,它让我们能够以POJO的形式定义Aspect,没有其它接口限制。唯一需要的,就是使用相应的注解标注这些Aspect定义的POJO类。之后SpringAOP会根据标注的注解搜索这些Aspect定义类,
然后将其织入系统。
其实SpringAOP只使用AspectJ的类库进行Pointcut的解析和匹配,最终的实现机制还是Spring AOP最初的架构,也就是使用代理模式处理横切逻辑的织入。
定义一个切面类的一般方法为:
使用@Aspect标注Aspect类,@Pointcut的注解指定Pointcut定义,@Around等注解指定哪些方法定义了相应的Advice逻辑
通过一个来说明
@Aspect
public class PerformanceTraceAspect {
private final Log logger=LogFactory.getLog(PerformanceTraceAspect.class);
@Pointcut("execution(public void *.method1())||execution(public void *.method2())")
public void pointcutName(){}
@Around("pointcutName()")
public Object performanceTrace(ProceedingJoinPoint joinpoint)throws Throwable
{
try{
System.out.println("start.......");
return joinpoint.proceed();
}finally{
System.out.println("stop......");
if(logger.isInfoEnabled()){
logger.info("PT in method["+joinpoint.getSignature().getName()+"]>>>>>");
}
}
}
}
public class Foo {
public void method1(){
System.out.println("method1 execution");
}
public void method2(){
System.out.println("method2 execution");
}
public void method3(){
System.out.println("method3 execution");
}
public void doSomething(String str){
System.out.println(str+"do something");
}
}
(1)通过编程方式织入:
public class aspectProgrammingTest {
@Test
public void test() {
AspectJProxyFactory weaver=new AspectJProxyFactory();
weaver.setProxyTargetClass(true);
weaver.setTarget(new Foo());
weaver.addAspect(PerformanceTraceAspect.class);
Object proxy=weaver.getProxy();
((Foo)proxy).method1();
((Foo)proxy).method2();
}
}
通过自动代理织入
针对@AspectJ风格的AOP,Spring AOP专门提供了一个AutoProxyCreator实现类进行自动代理,以免去过多编码和配置的工作,
只需要在IoC容器的配置文件中注册一下AnnotationAwareAspectJAutoProxyCreator就可以了。
实现如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
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-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/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<!-- 基于XSD的配置方式 -->
<aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>
<!-- 基于DTD的配置方式 -->
<!-- <bean
class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator">
<property name="proxyTargetClass" value="true"></property>
</bean> -->
<bean id="performanceTraceAspect" class="aop.spring.aspectTest.YourAspect"/>
<bean id="target" class="aop.spring.aspect.Foo"/>
</beans>
测试类:
public class aspectXmlTest {
@Test
public void test() {
ApplicationContext ctx=new ClassPathXmlApplicationContext("/beans.xml");
Object proxy=ctx.getBean("target");
((Foo)proxy).method1();
((Foo)proxy).method2();
((Foo)proxy).doSomething("zhsi...");
}
}
2、基于Schema的AOP
新的基于Schema的AOP配置方式,针对Pointcut、Advisor以及Aspect等概念提供了独立的配置元素,所有这些配置元素都包含在统一的
配置元素中,即<aop:config>
<aop:config>有三个子元素,分别是<aop:pointcut>、<aop:advisor>、 <aop:aspect>.它们三个必须按照顺序进行配置
实现的例子如下:
基于Schema的Advice声明也分为两部分,即Advice的定义和Advice的到容器的配置
Advice的定义如下:
public class SchemaBaseAspect {
public void doBefore(JoinPoint jp){
System.out.println("before method[ "+jp.getSignature().getName()+" ] execution");
}
public void doAfterReturning(JoinPoint jp){
System.out.println("method["+jp.getSignature().getName()+"]completed successfully");
}
public Object doAround(ProceedingJoinPoint pjp) throws Throwable{
System.out.println("around start.....");
Object reVal=pjp.proceed();
System.out.println("around end....");
return reVal;
}
}
配置声明如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
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-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/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<bean id="schemaBaseAspect" class="com.aop.spring.SchemaBaseAspect"></bean>
<aop:config>
<aop:aspect id="myAspect" ref="schemaBaseAspect" order="2">
<aop:pointcut id="privatepoint" expression="execution(public void *.doSth())"></aop:pointcut>
<aop:before pointcut-ref="privatepoint" method="doBefore"></aop:before>
<aop:after-returning pointcut-ref="privatepoint" method="doAfterReturning"></aop:after-returning>
<aop:around pointcut-ref="privatepoint" method="doAround"></aop:around>
</aop:aspect>
</aop:config>
<bean id="targetFoo" class="com.aop.spring.TargetFoo"></bean>
</beans>
测试类如下:
public class XSDTest {
@Test
public void test() {
ApplicationContext ctx=new ClassPathXmlApplicationContext("beans1.xml");
TargetFoo f=(TargetFoo) ctx.getBean("targetFoo");
f.doSth();
}
}
对于Introduction类型的advice有其独特的实现方式,这里就不再详细介绍了。
到目前为止,我们接触了如下三种Spring AOP的使用方式
(1) Spring AOP 1.x 版本发布的基于接口定义的Advice声明方式。这种方式的特点是,各种类型的Advice定义需要实现特定的接口,Advice的管理可以通过IoC
容器或者直接编程来进行。我们将其称为第一代Spring AOP
(2)@AspectJ形式的AOP是在Spring2.0发布之后新增加的一种Spring AOP使用方式。在这种方式中,我们只需要以POJO的形式声明相应的Aspect和Advice,然后通过
相应的注解标注一下即可,
(3)基于Schema的AOP也是在Spring2.0发布之后增加的Spring AOP使用方式,它融合了第一代Spring AOP和@AspectJ 形式的优点,不但完全支持第一代Spring AOP
的配置需求,而且在@Aspect形式的AOP的基础之上进行了改装:我们依然可以通过POJO声明Aspect和Advice定义,不过,通过相应
注解表达的各种信息,转移到了XSD形式的容器配置文件中。
对于如何在这三种方式之间进行选择,应该依照当前应用环境、各种工具支持、整体团队对各种方式的熟悉程度等不同情况来权衡利弊,最终决定一种合适的方式。
目前对于我来说,我还只是在学习阶段,所以对于选择哪一种Spring AOP 方式我还不是有所体会。
what do you want? </span>
Spring AOP的实现机制(三)---@AspectJ形式的Spring AOP和基于Schema的AOP
最新推荐文章于 2020-04-19 00:11:25 发布