谈谈你对SpringAOP理解【⾯试】
前⾔
⾯试中经常会被问到Spring AOP的原理,相信⼤家都是条件反射的想到JDK动态代理和CGLib动态代理,本⽂将介绍这两个代理的区别及实现⼀个Spring AOP实例。
1、为什么会有AOP
AOP的全称是Aspect Oriented Programming,翻译成中⽂是⾯向切⾯编程。当我们在开发⽇志、权限验证、事务等功能时,如果不使⽤AOP,只能在每个对象⾥引⽤公共⾏为,这样做不便于维护,⽽且有⼤量重复代码,AOP的出现就是解决这些问题。
2、Spring AOP的原理
Spring Aop中使⽤的代理有两种⽅式,⼀种是Jdk的动态代理,另⼀种是基于CGLIB实现的代理,当我们的bean对象实现了某⼀接⼝
后,Spring默认将采⽤Jdk动态代理,当我们的bean对象没有实现接⼝时,默认将采⽤CGLIB代理,Spring也⽀持我们在bean对象实现了接⼝时也强制的使⽤CGLIB代理。Spring的Bean容器在初始化bean
对象的时候就会判断对应的bean是否需要进⾏切⾯编程,即是否需要对其进⾏代理,如果需要,则初始化的时候就会把它初始化为⼀个代理对象。
3、Jdk动态代理
JDK动态代理基于和反射来实现。
JDK动态代理是不需要第三⽅库⽀持的,只需要JDK环境就可以进⾏代理。
使⽤的条件:
1. 必须实现InvocationHandler接⼝;
2. 使⽤wProxyInstance产⽣代理对象;
3. 被代理的对象必须要实现接⼝;
4、CGLib动态代理
CGLib包的底层是通过使⽤⼀个⼩⽽快的字节码处理框架ASM,来转换字节码并⽣成新的类。
CGLib是针对类实现代理,主要是对指定的类⽣成⼀个⼦类,覆盖其中的⽅法,并覆盖其中⽅法实现增强。
使⽤条件
1. CGLib是针对类实现代理,采⽤的是继承,类或⽅法不要声明成final;
2. 必须实现MethodInterceptor接⼝;
3. 需要使⽤CGLib包;
5、spring aop 实践
1. 编写测试类
//user接⼝
public interface UserDao {
//登录
void login();
}
//user实现类,测试jdk代理
public class MyUserDao implements UserDao {
@Override
public void login(){
System.out.println("接⼝⽤户正常登录");
}
}
//⽆接⼝实现,测试cglib
public class CglibDao {
public void cglibLogin(){
System.out.println("cglib⽤户正常登录");
}
}
//⾃定义切⾯类
public class MyAspect {
public void begin(){
System.out.println("[前置通知]  开启事务..");
}
public void commit(){
System.out.println("[后置通知] 提交事务..");
}
public void after(){
System.out.println("[返回后通知]");
}
public void afterThrowing(){
System.out.println("[异常通知]");
}
public void arroud(ProceedingJoinPoint pjp)throws Throwable {        System.out.println("[环绕前:]");
pjp.proceed();// 执⾏⽬标⽅法
System.out.println("[环绕后:]");
}
}
/
/测试类
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(value ={"l"}) public class AopTest {
@Resource
UserDao userDao;
@Resource
CglibDao cglibDao;
@Test
public void testUser(){
userDao.login();
}
@Test
public void testCglib(){
}
}
配置⽂件l
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="/schema/beans"
xsi="/2001/XMLSchema-instance"
aop="/schema/aop"
schemaLocation="/schema/beans
/schema/beans/spring-beans.xsd
/schema/aop
/schema/aop/spring-aop.xsd">
<!-- dao实例加⼊容器 -->
<bean id="myUserDao"class="aop.MyUserDao"></bean>
<!-- dao实例加⼊容器 -->
<bean id="cglibDao"class="aop.CglibDao"></bean>
<!-- 实例化切⾯类 -->
<bean id="myAspect"class="aop.MyAspect"></bean>
<!-- Aop相关配置 -->
<config>
<!-- 切⼊点表达式定义 -->
<pointcut expression="execution(* aop.*Dao.*(..))"id="transactionPointcut"/> <!-- 切⾯配置 -->
<aspect ref="myAspect">
<!-- 【环绕通知】 -->
<around method="arroud"pointcut-ref="transactionPointcut"/>
<!-- 【前置通知】在⽬标⽅法之前执⾏ -->
<before method="begin"pointcut-ref="transactionPointcut"/>
<!-- 【后置通知】 -->
<after method="commit"pointcut-ref="transactionPointcut"/>
<!-- 【返回后通知】 -->
<after-returning method="after"pointcut-ref="transactionPointcut"/>
<!-- 异常通知 -->
<after-throwing method="afterThrowing"pointcut-ref="transactionPointcut"/> </aspect>
</config>
</beans>
输出结果:
spring aop应用场景
结束语
本篇详细的介绍了Jdk动态代理和Cglib代理,以及⼿写了⼀个spring aop的实例,熟悉spring aop的配置。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。