spring -7 aop编程
作者:互联网
目录
aop编程
1,为什么需要代理设计模式?
在javaee分层开发中,service层对于我们来说很重要,该层包括了dao,事务操作,也就是核心业务,而有一些代码,比如说事务,日志,性能(程序执行时间)代码量少,不属于核心业务,可有可无。
站在调用者的角度,需要,站在设计者的角度(我实现功能就行了),不需要。
2,现实生活中代理的解决方案--租房。
房东:核心功能(签合同,收房租);额外功能(放广告,带人看房);
房客:我需要房子住,但是我也需要实地看房。
中介:引入代理,代替房东去做一些它不想做的工作,比如说投放广告,带人看房,但是核心功能(签合同,收房租),还是让房东来。
3,静态代理存在的问题
静态文件过多,不利于项目的管理。维护功能差,额外功能修改复杂(麻烦)。
4,解决方案-spring动态代理开发。
代理三要素:原始对象,额外功能,组装。
spring的两种方法(MethodBeforeAdvice接口和MethodInterceptor接口)。直接使用MethodInterceptor接口。
MethodInterceptor可以在原始方法执行之前,之后添加额外方法。而MethodBeforeAdvice只会在之前(不灵活)。
5,spring动态代理编码。
spring动态代理四步: 目标对象(实现类),额外功能(MethodInterceptor),切入点(aop:pointcut),组装(aop:advisor)
public class UserDaoImpl implements IUserDao{
@Override
public void save(Person person) {
System.out.println("dao save...");
}
@Override
public void query(String name) {
System.out.println("dao query name "+ name);
}
}
<!-- 原始对象-->
<bean id="userDao" class="core.UserDaoImpl"></bean>
<!-- 额外功能-->
<bean id="around" class="aop.MyAspect"></bean>
<aop:config>
<!-- 定义切入点-->
<aop:pointcut id="pc" expression="execution(* query(..))"/>
<!-- 组装-->
<aop:advisor advice-ref="around" pointcut-ref="pc"></aop:advisor>
</aop:config>
test代码
/**
* 测试:spring工厂得到代理对象
*/
@org.junit.Test
public void test5(){
ApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext.xml");
IUserDao userDao = (IUserDao) ctx.getBean("userDao");
userDao.query("jackson");
}
结果:
备注:1,MethodInterceptor会影响原始方法的返回值,必须返回ret(原始方法执行结果)。
2,spring通过id获得的是代理对象(详情在spring -6补充中)
6,细节补充
在动态代理时,没有看到代理类的存在,spring框架在运行时,class文件在JVM内创建,运行在JVM内部,等待程序结束后,随JVM一起消失。
spring默认使用JDK动态代理,springboot默认使用cglib。
<!--Proxy -target-class 默认false,运行JDK,true,运行cglib-->
<aop:config proxy-target-class="true">
<!-- 定义切入点-->
<aop:pointcut id="pc" expression="execution(* query(..))"/>
<!-- 组装-->
<aop:advisor advice-ref="around" pointcut-ref="pc"></aop:advisor>
</aop:config>
标签:功能,aop,spring,编程,代理,MethodInterceptor,public 来源: https://blog.csdn.net/weixin_46083389/article/details/113683155