基于代理类的AOP的实现
Posted nuist__NJUPT
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于代理类的AOP的实现相关的知识,希望对你有一定的参考价值。
基于代理类的AOP的实现
- 在spring中默认使用JDK动态代理实现AOP编程,使用代理类创建代理是SpringAOP实现的最基本的方式
- 根据Spring中通知在目标方法中的连接点的位置,通知可以分为下面6种类类型
- 1-环绕通知:在目标方法执行前和执行后实施增强,可以用于日志记录,事务处理。
- 2-前置通知:在目标方法执行前实施增强,可以应用于权限管理等功能。
- 3-后置返回通知:在目标方法执行后实施增强,可以用于关闭流,删除临时文件等。
- 4-后置最终通知:在目标方法执行后实施增强,不管是否发生异常都要执行该类通知,该类通知可用于释放资源。
- 5-异常通知:在方法抛出异常后实施增强,可以用于处理异常,记录日志等功能。
- 6-引入通知:在目标类中添加一些新的方法和属性,可以应用于修改目标类。
- ProxyFactoryBean是一个接口的实现类,FactoryBean负责实例化一个Bean实例,ProxyFactoryBean负责为其它Bean创建代理实例。
- ProxyFactoryBean类的常用属性:
- 1-target:代理的目标对象
- 2-proxyInterfaces:代理需要实现的接口
- 3-interceptorNames:需要织入目标的Advice
- 4-proxyTargetClass:是否对类代理而不是接口,默认为false,使用JDK代理,当为true,使用CGLIB代理
- 5-singleton:返回的代理实例是否为单例,默认为true
- 6-optimize:当设置为true时候,强制使用CGLIB代理
本次使用的开发环境是IDEA
通过一个环绕通知的实例演示Spring使用ProxyFactoryBean创建AOP代理的过程.
1-使用IDEA创建Spring项目,库Libraries选择DownLoad,自当下载所需的jar包,无需导入
自动默认导入的jar包如下:
2-在src目录下创建包dynamic.jdk,并在该包中创建接口TestDao和接口的实现类TestDaoImpl.
public interface TestDao {
public void save() ;
public void modify() ;
public void delete() ;
}
public class TestDaoImpl implements TestDao {
@Override
public void save() {
System.out.println("保存") ;
}
@Override
public void modify() {
System.out.println("修改") ;
}
@Override
public void delete() {
System.out.println("删除") ;
}
}
3-在src目录创建包spring.proxyfactorybean包,并在该包中创建切面类MyAspect
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
//通过一个环绕通知的实例演示Spring使用ProxyFactoryBean创建AOP代理的过程
public class MyAspect implements MethodInterceptor {
public void check(){
System.out.println("模拟权限控制") ;
}
public void except(){
System.out.println("模拟异常处理") ;
}
public void log(){
System.out.println("模拟日志记录") ;
}
public void monitor(){
System.out.println("模拟性能监控") ;
}
@Override
public Object invoke(MethodInvocation methodInvocation) throws Throwable { //重写invoke接口方法
//前增强
check() ;
except() ;
//执行目标方法
Object object = methodInvocation.proceed() ;
//后增强
log() ;
monitor() ;
return object;
}
}
4-为切面类配置bean实例,是Spring容器识别切面对象
<?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:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util https://www.springframework.org/schema/util/spring-util.xsd">
<!--定义目标对象-->
<bean id = "testDao" class = "dynamic.jdk.TestDaoImpl"/>
<!--创建一个切面-->
<bean id = "MyAspect" class = "spring.proxyfactorybean.MyAspect"/>
<!--使用Spring代理工厂定义一个名为testDaoProxy的代理对象-->
<bean id = "testDaoProxy" class = "org.springframework.aop.framework.ProxyFactoryBean">
<!--指定代理实现的接口-->
<property name="proxyInterfaces" value = "dynamic.jdk.TestDao"/>
<!--指定目标对象-->
<property name = "target" ref = "testDao"/>
<!--指定切面,织入环绕通知-->
<property name = "interceptorNames" value = "MyAspect"/>
</bean>
</beans>
5-在spring.proxyfactorybean包中创建测试类ProxyFactoryBeanTest测试类,在main方法中使用Spring容器获取增强后的目标对象,并执行目标方法。
import dynamic.jdk.TestDao;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* 创建测试类,在主方法中使用Spring容器获取增强后的目标对象,并执行目标方法
*/
public class ProxyFactoryBeanTest {
public static void main(String[] args){
//初始化Spring容器,并加载配置文件
ApplicationContext appCon = new ClassPathXmlApplicationContext("spring-config.xml") ;
//从容器中获取增强后目标对象
TestDao testDaoAdvice = (TestDao) appCon.getBean("testDaoProxy");
//执行方法
testDaoAdvice.save() ;
System.out.println("================") ;
testDaoAdvice.modify() ;
System.out.println("================") ;
testDaoAdvice.delete() ;
System.out.println("================") ;
}
}
6-测试结果入下:
以上是关于基于代理类的AOP的实现的主要内容,如果未能解决你的问题,请参考以下文章