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

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

看一下工作原理

SpringAction学习二、高级装配:通过注解引入新功能_第1张图片

示例代码

接口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到底是个啥

SpringAction学习二、高级装配:通过注解引入新功能_第2张图片

注意红框:

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

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

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

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

SpringAction学习二、高级装配:通过注解引入新功能_第3张图片

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

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

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

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

 

xml方式配置




    

    
        
            
        
    

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




    
    

    
        
            
                    
                    
                    
        
    
    
        
            
        
    

 

你可能感兴趣的:(SpringAction,示例代码)