Spring全家桶面试题(一)之Spring Framework(七)

五、Spring AOP(续)

53. 什么情况下AOP会失效,怎么解决?

1. 失效原因

  1. 方法是private也会失效,解决:改成public
  2. 目标类没有配置为Bean也会失效, 解决:配置为Bean,因为SpringAOP只会为Bean创建动态代理
  3. 切点表达式没有配置正确
  4. 内部调用不会触发AOP(cglib本可以)

2. 内部调用不会触发AOP

  1. 在本类中自动注入当前的bean
@Service
//@Lazy       //懒加载,除非注入使用了,才会被spring托管    默认eager,即不需要注入就加载
//@Scope("prototype")     singleton默认单例
public class StudentBizImpl implements StudentBiz{

    //如果发现实现了AOP,就会创建动态代理,Spring容器中就只会有代理对象了,注入的也是动态代理对象
    @Autowired
    private  StudentBiz studentBiz;
   public int add(String name){
       System.out.println("============业务层==============");
       System.out.println("用户名是否重名");
       int result=studentDao.add(name);
       studentBiz.update(name);
       System.out.println("============业务层操作结束2==========");
       return result;
   }
  1. 设置暴露当前代理对象到本地线程, 可以通过AopContext.currentProxy() 拿到当前正在调用的动态代理对象
 @EnableAspectJAutoProxy(exposeProxy = true)
AopContext.currentProxy() 拿到当前正在调用的动态代理对象
public int mod(int numA,int numB){
	System.out.println("执行目标方法:mod");
	//获取当前线程的动态代理对象,防止调用本类的方法,不会进行增强(cglib本身就实现了,这个主要用于JDK)
	int retVal=((Caculate)AopContext.currentProxy()).add(numA,numB);
	int retVal=this.add(numA,numB);
	return retVal%numA;
}

54.Spring的AOP是在哪里创建的动态代理?

  1. 正常的Bean会在Bean的生命周期的初始化后, 通过BeanPostProcessor.postProcessAfterInitialization创建aop的动态代理
  2. 还有一种特殊情况: 循环依赖的Bean会在Bean的生命周期属性注入时存在的循环依赖的情况下, 也会为循环依赖的Bean通过MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition创建aop

55. Spring的 Aop的完整实现流程?

Aop的实现大致分为三大步:JavaConfig
当@EnableAspectJAutoProxy 会通过@Import注册一个BeanPostProcessor处理AOP

  1. 解析切面: 在Bean创建之前的第一个Bean后置处理器会去解析切面(解析切面中通知、切点,一个通知就会解析成一
    个advisor(通知、切点))
  2. 创建动态代理:正常的Bean初始化后调用BeanPostProcessor,拿到之前缓存的advisor ,再通过advisor中pointcut
    判断当前Bean是否被切点表达式匹配,如果匹配,就会为Bean创建动态代理(创建方式1.jdk动态代理2.cglib)。
  3. 调用:拿到动态代理对象, 调用方法就会判断当前方法是否增强的方法,如果是就会通过调用链的方式依次去执行通知
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值