美文网首页程序员
spring的AOP知识点2.0

spring的AOP知识点2.0

作者: 知识学者 | 来源:发表于2018-09-18 17:51 被阅读95次

AOP相关概念
Joinpoint(连接点):所谓连接点是指那些被拦截到的点。在spring中,这些点指的是方法,因为spring只支持方法类型的连接点.

Pointcut(切入点):所谓切入点是指我们要对哪些Joinpoint进行拦截的定义.

Advice(通知/增强):所谓通知是指拦截到Joinpoint之后所要做的事情就是通知.通知分为前置通知,后置通知,异常通知,最终通知,环绕通知(切面要完成的功能)

Introduction(引介):引介是一种特殊的通知在不修改类代码的前提下, Introduction可以在运行期为类动态地添加一些方法或Field.

Target(目标对象):代理的目标对象
Weaving(织入):是指把增强应用到目标对象来创建新的代理对象的过程.

spring采用动态代理织入,而AspectJ采用编译期织入和类装在期织入

Proxy(代理):一个类被AOP织入增强后,就产生一个结果代理类

Aspect(切面): 是切入点和通知(引介)的结合

二、 AOP 的底层实现
AOP 底层使用的代理技术 : JDK动态代理 和 CGlib的动态代理。
AOP 开发规范 : AOP联盟为通知Advice定义了org.aopalliance.aop.Interface.Advice。 Spring AOP 实现 AOP联盟定义 规范

传统Spring AOP 提供 五类 Advice

a 前置通知(代码增强) org.springframework.aop.MethodBeforeAdvice 在目标方法执行前实施增强

b 后置通知 org.springframework.aop.AfterReturningAdvice 在目标方法执行后实施增强

c 环绕通知org.aopalliance.intercept.MethodInterceptor 在目标方法执行前后实施增强

d 异常抛出通知 org.springframework.aop.ThrowsAdvice 在方法抛出异常后实施增强

e 引介通知 org.springframework.aop.IntroductionInterceptor 在目标类中添加一些新的方法和属性

2、 Spring 的切面 Advisor
Advisor 就是对PointCut 应用 Advice (通常所说Advisor 指只有一个Point 和 一个 Advice )

通过配置实现增强
采用jdk动态代理实现,有一个接口UserService,实现类 UserImpl, 不配置切点

UserService接口

package dflx;

public interface UserService {
    
    public void add();
    
    public void serach();
}

实现类 UserImpl

public class UserImpl implements UserService {

    @Override
    public void add() {
    System.out.println(" add user");
    }

    @Override
    public void serach() {
    System.out.println("search user");

    }

}

AOP的配置如下

<?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="user" class="dflx.UserImpl"></bean>
<!-- 增强 -->
<bean id="mybeforeadvice" class="dflx.MethodBeforeTest"></bean>
<bean id="userDAOProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<!-- 目标 -->
<property name="target" ref="user"></property>
<!-- 针对接口代理 -->
<property name="proxyInterfaces" value="dflx.UserService"></property>
<property name="interceptorNames" value="mybeforeadvice"></property>
</bean>

</beans>
image.png

通过如下方法测试

@Test
    public void test() {
        ApplicationContext app=new ClassPathXmlApplicationContext("app.xml");
        UserService user=(UserService) app.getBean("userDAOProxy");
        user.add();
        user.serach();
    }

结果如下

 前置增强-----------
 add user
 前置增强-----------
search user
image.png

采用Cglib的动态代理,有切点和切面。
有一个 OrderDAO类,Advice通知增强类MyMethodInterceptor

public class OrderDAO {
    
    public void add() {
        System.out.println(" 添加订单");
    }

    public void delete() {
        System.out.println(" 删除订单");
    }
    
    public void search() {
        System.out.println(" 查询订单");
    }
}

Advice通知增强类

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class MyMethodInterceptor implements MethodInterceptor {

    @Override
    public Object invoke(MethodInvocation arg) throws Throwable {
        System.out.println("环绕前增强");
        Object resultObject=arg.proceed(); //目标方法执行
        System.out.println("环绕后增强");
        return resultObject;
    }

}

AOP的配置如下

<?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="orderDAO" class="day0916.OrderDAO"></bean>
<!-- 增强 -->
<bean id="mymethodinter" class="day0916.MyMethodInterceptor"></bean>
<!-- 定义切点切面 -->
<bean id="myadvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="pattern" value=".*"></property>
<property name="advice" ref="mymethodinter"></property>
</bean>

<!-- 创建代理 -->
<bean id="orderDAOProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<!-- 目标 -->
<property name="target" ref="orderDAO"></property>
<!-- 针对类代理 -->
<property name="proxyTargetClass" value="true"></property>
<!-- 增强 -->
<property name="interceptorNames" value="myadvisor"></property>
</bean>
</beans>

测试类如下


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:app2.xml")
public class SpringTest {
    
    @Autowired
    @Qualifier("orderDAOProxy")
    private OrderDAO orderDAO;
    
    @Test
    public void test() {
        orderDAO.add();
        orderDAO.search();
        orderDAO.delete();
    }

}

结果如下

环绕前增强
 添加订单
环绕后增强
环绕前增强
 查询订单
环绕后增强
环绕前增强
 删除订单
环绕后增强
image.png

相关文章

网友评论

    本文标题:spring的AOP知识点2.0

    本文链接:https://www.haomeiwen.com/subject/avaxnftx.html