为了账号安全,请及时绑定邮箱和手机立即绑定

spring的AOP知识点2.0

标签:
Java

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

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
全栈工程师
手记
粉丝
73
获赞与收藏
369

关注作者,订阅最新文章

阅读免费教程

  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消