美文网首页
Spring AOP注解@DeclareParents的使用

Spring AOP注解@DeclareParents的使用

作者: 仿若尘土 | 来源:发表于2019-03-14 13:45 被阅读0次

[TOC]

1. 概念

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

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

2. 通过@DeclareParents注解实现

2.1 maven依赖

        <!--spring的context上下文即IoC容器-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <!--spring aop依赖-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <!--spring测试依赖-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring.version}</version>
            <scope>test</scope>
        </dependency>

        <!--junit依赖-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

        <!--spring aop依赖AspectJ-->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.2</version>
        </dependency>

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:

<?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:context="http://www.springframework.org/schema/context" xmlns:c="http://www.springframework.org/schema/c"
       xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

    <bean id="iWaitingProxy" class="com.cui.springShizhan.ch4.DeclareParents.WaitingProxyImpl"/>
    <bean id="iDeclareParentProxy" class="com.cui.springShizhan.ch4.DeclareParents.DeclareParentProxyImpl"/>

    <aop:config proxy-target-class="true">
        <aop:aspect>
            <aop:declare-parents
                    types-matching="com.cui.springShizhan.ch4..*"
                    implement-interface="com.cui.springShizhan.ch4.DeclareParents.IDeclareParentProxy"
                    delegate-ref="iDeclareParentProxy"/>
        </aop:aspect>
    </aop:config>
</beans>

方式2:

<?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:context="http://www.springframework.org/schema/context" xmlns:c="http://www.springframework.org/schema/c"
       xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

    <bean id="iWaitingProxy" class="com.cui.springShizhan.ch4.DeclareParents.WaitingProxyImpl"/>

    <aop:config proxy-target-class="true">
        <aop:aspect>
            <aop:declare-parents
                    types-matching="com.cui.springShizhan.ch4..*"
                    implement-interface="com.cui.springShizhan.ch4.DeclareParents.IDeclareParentProxy"
                    default-impl="com.cui.springShizhan.ch4.DeclareParents.DeclareParentProxyImpl"/>
        </aop:aspect>
    </aop:config>
</beans>

属性解释:

  • 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的使用

      本文链接:https://www.haomeiwen.com/subject/swvfmqtx.html