关于增强,目前有四个方法
1、通过编程式增强,也就是定义一个接口,然后再创建一个实现类,接着创建一个通知(advice),如果是前置和后置通知,那么需要实现MethodBeforeAdvice和AfterReturningAdvice这两个接口,然后实现两个接口中的方法。前面部分处理完,写测试类的时候,需要创建一个代理工厂,然后向代理工厂设置目标对象(setTarget()),写入通知的实现类对象addAdvice(类对象),测试图如下所示:
![](https://img.haomeiwen.com/i13278348/ed19c74e9089a30b.png)
如果是环绕通知,那么就需要实现MethodInterceptor接口,实现invoke()方法,注意参数是MethodInvocation类型。
2、申明式增强,这种方式的增强就需要向xml文档中写入代理工厂的参数
<bean id="proxyFactory" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="interfaces" value="接口" />
<property name="target" ref="目标对象的bean id" />
<property name="interceptorNames" value="通知类对象的bean id" />
</bean>
这种方式可以用<context:component-scan base-package="包名" />方式去扫描包里边带有四大组件的类,并且生成一个bean,bean的id为类名(首字符小写)
四大组件分别@Component @Service @Controller @Repository(持久层)
3、引入式增强,引入式增强首先是在申明式增强的配置文件中添加一个参数属性的设置
<property name="proxyTargetClass" value="true" />
说明:
<bean id="proxyFactory" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="interfaces" value="接口" />
<property name="target" ref="目标对象的bean id" />
<property name="interceptorNames" value="通知类对象的bean id" />
<property name="proxyTargetClass" value="true" />
<!-- 代理目标类,设置true则为cglib动态代理,否则jdk动态代理 -->
</bean>
引入增强类,比如a实现了A接口,然后现在想让a不实现B接口,但是却可以调用B接口中的方法,这就是引入增强类想达到的效果。
首先创建接口B,然后将接口B的通知和实现用一个类来实现,也就是接口B的通知类也是他的实现类,即需要继承DelegatingIntroductionInterceptor
类并且实现接口B。测试类可以按照下面的方式书写:
![](https://img.haomeiwen.com/i13278348/43001b97e7c9ccf0.png)
4、启用Spring对@AspectJ切面配置的支持
配置头
<?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"
xmlns:context="http://www.springframework.org/schema/context"
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
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<!-- 启动@AspectJ支持 -->
<aop:aspectj-autoproxy/>
</beans>
<aop:aspectj-autoproxy proxy-target-class="true"/>开启@Aspectj支持
proxy-target-class属性值决定是基于接口的还是基于类的代理被创建。首先说明下proxy-target-class="true"和proxy-target-class="false"的区别,为true则是基于类的代理将起作用(需要cglib库),为false或者省略这个属性,则标准的JDK 基于接口的代理将起作用。
接下来还需要在xml配置文件中写入:
<!-- 指定自动搜索Bean组件,自动搜索切面类 -->
<context:component-scan base-package="bean组件包名">
<context:include-filter type="annotation"
expression="org.aspectj.lang.annotation.Aspect" />
</context:component-scan>
这样子在通知类前加上注释@Aspect就能够被配置文件扫到,不然这个类作用不到当前项目中去。
参考链接:
https://www.cnblogs.com/ssslinppp/p/4633364.html
https://www.cnblogs.com/sunfie/p/4785162.html
https://my.oschina.net/itblog/blog/210718
https://blog.csdn.net/sinat_28978689/article/details/62048539
网友评论