Spring AOP注解@DeclareParents的使用

[TOC]

1. 概念

Spring AOP提供的@Before@After@AfterReturning@AfterThrowingAround只对类的现有方法进行增强处理。如果需要对现有类增加新的方法,有两种方法可实现:

  1. 扩展现有类:实现简单,但如果对多个现有类进行扩展时,需增加多个类
  2. 使用@DeclareParents注解实现:实现复杂,可使用通配符匹配
    本文介绍@DeclareParents注解实现的增强。

2. 通过@DeclareParents注解实现

2.1 maven依赖

        
        
            org.springframework
            spring-context
            ${spring.version}
        

        
        
            org.springframework
            spring-aop
            ${spring.version}
        

        
        
            org.springframework
            spring-test
            ${spring.version}
            test
        

        
        
            junit
            junit
            4.12
            test
        

        
        
            org.aspectj
            aspectjweaver
            1.9.2
        

2.2 实现

  1. 待增强功能
package com.cui.springShizhan.ch4.DeclareParents;

public interface IWaitingProxy {
    public void method();
}

package com.cui.springShizhan.ch4.DeclareParents;

import org.springframework.stereotype.Component;

@Component
public class WaitingProxyImpl implements IWaitingProxy {
    @Override
    public void method() {
        System.out.println("现有方法");
    }
}
  1. 代理类
package com.cui.springShizhan.ch4.DeclareParents;

public interface IDeclareParentProxy {
    public void declareParentProxy();
}

package com.cui.springShizhan.ch4.DeclareParents;

import org.springframework.stereotype.Component;

@Component
public class DeclareParentProxyImpl implements IDeclareParentProxy{
    @Override
    public void declareParentProxy() {
        System.out.println("我是增强代理方法");
    }
}
  1. 切面配置
package com.cui.springShizhan.ch4.DeclareParents;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.DeclareParents;
import org.springframework.stereotype.Component;

@Component
@Aspect
public class AspectJIntroductionAnnotationAdvice {
    @DeclareParents(value = "com.cui.springShizhan.ch4.DeclareParents.*", defaultImpl = DeclareParentProxyImpl.class)
    private IDeclareParentProxy iDeclareParentProxy;
}

说明:

  • value:相当于XML中的types-matching,待引入增强作用的类的表达式, 支持通配符
  • defaultImpl:引入增强的具体实现
  1. spring配置
package com.cui.springShizhan.ch4.DeclareParents;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@Configuration
@ComponentScan("com.cui.springShizhan.ch4")
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class AppConfig {
}
  1. 单元测试
package springshizhan.ch4;

import com.cui.springShizhan.ch4.DeclareParents.AppConfig;
import com.cui.springShizhan.ch4.DeclareParents.IDeclareParentProxy;
import com.cui.springShizhan.ch4.DeclareParents.IWaitingProxy;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import javax.annotation.Resource;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = AppConfig.class)
public class DeclareParentsAnnotationTest {
    @Resource
    private IWaitingProxy iWaitingProxy;

    @Test
    public void test() {
        iWaitingProxy.method();
        IDeclareParentProxy iDeclareParentProxy = (IDeclareParentProxy) iWaitingProxy; 
        iDeclareParentProxy.declareParentProxy();
    }
}
/*结果
现有方法
我是增强代理方法
*/

3. 通过XML配置实现

主要区别为配置文件:
方式1:




    
    

    
        
            
        
    

方式2:




    

    
        
            
        
    

属性解释:

  • types-matching:待增强类的表达式,支持通配符
  • implement-interface:引入增强的方法所在的接口
  • delegate-ref:引入增强的实现bean的id(方式1
  • default-impl:引入增强的实现类的全路径名称(方式2,使用该方式,无需把增强类的Bean注入到Spring容器中)
    注:delegate-refdefault-impl仍选一个实现即可

4. 参考

  1. Spring源码-AOP(八)-引入增强
  2. spring-AOP通过注解@DeclareParents引入新的方法
  3. 《Spring 实战》第4版

你可能感兴趣的:(Spring AOP注解@DeclareParents的使用)