SpringAction学习二、高级装配:通过注解引入新功能

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/MASORL/article/details/82688923

因为不是很好理解,所以单独放在一章上来记录

看一下工作原理

示例代码

接口1

package com.spring.chapter4.addmethod;

public interface BeNotified {
    void aspectStart();
    void aspectStart(int b);
}

接口1实现

package com.spring.chapter4.addmethod;

import org.springframework.stereotype.Component;

@Component
public class BeNotifiedImpl implements BeNotified {
    public void aspectStart() {
        System.out.println("主体方法");
//        throw new RuntimeException();
    }

    public void aspectStart(int b) {

    }
}

接口2:

package com.spring.chapter4.addmethod;

public interface Encoreable {
    void perfor();
}

接口2实现类

package com.spring.chapter4.addmethod;

import org.springframework.stereotype.Component;

@Component
public class EncoreableImpl implements Encoreable {
    public void perfor() {
        System.out.println("新增的方法!");
    }
}

切面2

package com.spring.chapter4.addmethod;

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

@Component
@Aspect
public class EncoreableIntroducer {
    @DeclareParents(value = "com.spring.chapter4.addmethod.BeNotified+", defaultImpl = EncoreableImpl.class)
    public static Encoreable encoreable;
}

测试

package com.spring.chapter4.addmethod;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import static org.junit.Assert.*;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = AddmethodConfig.class)
public class AddmethodConfigTest {
    @Autowired
    private BeNotified beNotified;

    @Test
    public void test(){
        System.out.println(beNotified instanceof Encoreable);
        Encoreable beNotified = (Encoreable) this.beNotified;
        beNotified.perfor();
    }

}

测试结果

true
新增的方法!

打个断电看下beNotfied到底是个啥

注意红框:

(1)第一个红框,$Proxy,首先说明第一点,这个类,是一个代理。也就验证了spring aop是通过代理来封装目标对象

(2)第二个红框,targeSource指向了BeNotifiledImpl.也就是封装的目标对象

(3)第三个红框,查看它的接口,很明显,它除了继承了BeNotified接口,还继承了Encoreable。

一脸懵逼,看一下官方对@DeclareParents的解释

第一句话翻译过来的意思大概是:

Intrductions(在AspectJ中称为类型间声明),通过一个切面来声明访问对象实现给定接口,并代表这些对象提供该接口的实现。

换句话说,@DeclareParents可以通过切面为目标对象添加一个接口,并且提供这个对象的实例。

也就是我们在断点看到的。

xml方式配置

<?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: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/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

    <bean id="beNotified" class="com.spring.chapter4.xmladdmethod.BeNotifiedImpl"/>

    <aop:config>
        <aop:aspect>
            <aop:declare-parents
                    types-matching="com.spring.chapter4.xmladdmethod.BeNotified+"
                    implement-interface="com.spring.chapter4.xmladdmethod.Encoreable"
                    default-impl="com.spring.chapter4.xmladdmethod.EncoreableImpl"/>
        </aop:aspect>
    </aop:config>

</beans>

或者也可以通过delegate-ref来引入一个bean

<?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: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/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

    <bean id="beNotified" class="com.spring.chapter4.xmladdmethod.BeNotifiedImpl"/>
    <bean id="encoreable" class="com.spring.chapter4.xmladdmethod.EncoreableImpl"/>

    <!--<aop:config>-->
        <!--<aop:aspect>-->
            <!--<aop:declare-parents-->
                    <!--types-matching="com.spring.chapter4.xmladdmethod.BeNotified+"-->
                    <!--implement-interface="com.spring.chapter4.xmladdmethod.Encoreable"-->
                    <!--default-impl="com.spring.chapter4.xmladdmethod.EncoreableImpl"/>-->
        <!--</aop:aspect>-->
    <!--</aop:config>  -->
    <aop:config>
        <aop:aspect>
            <aop:declare-parents
                    types-matching="com.spring.chapter4.xmladdmethod.BeNotified+"
                    implement-interface="com.spring.chapter4.xmladdmethod.Encoreable"
                    delegate-ref="encoreable"/>
        </aop:aspect>
    </aop:config>

</beans>

猜你喜欢

转载自blog.csdn.net/MASORL/article/details/82688923