Spring AOP:spring 如何能够代理工厂创建的对象?

SpringAOP: How is spring able to proxy object created by factory?

我是 AOP 新手,正在慢慢阅读和学习 SpringAOP 和 AspectJ。

我有 运行 一个意想不到的例子,一个对象不是作为 bean 创建的,而是由作为 bean 创建的工厂创建的,而我的方面正在代理期望只有 spring 创建的对象被 SpringAOP 中的适用方面代理。

spring 如何知道要代理由在 spring 注册的工厂创建的对象?这意味着 spring 怎么知道我自己的工厂实际上是一个工厂,而 DogShelter.getAngryDog() 返回的对象是一个需要用代理包装的新对象,而不是一些现有的 AngryDog以前已经用方面代理包装了吗?

代码如下:

对象:

public class AngryDog extends Dog {
    @Override
    public void play() {
        System.out.println("AngryDog->play()");
        bark();
        bite();
    }

    @Override
    public void bark() {
        System.out.println("AngryDog->bark()");
    }

    @Override
    public void bite() {
        System.out.println("AngryDog->bite()");
    }
}

工厂:

public class DogShelter {
    public AngryDog getAngryDog(){
        return new AngryDog();
    }
}

看点:

@Aspect
public class BeforeAllDogMethodsAspect {

    @Before("execution(* com.demos.dogs.*.*(..)))")
    public void doAccessCheck() {
        System.out.println("SpringAOP aspect called!");
    }

}

Spring 配置:

/** DogConfig spring configuration */
@EnableAspectJAutoProxy
@Configuration
public class DogConfig {

    @Bean
    public AngryDog dog() {
        return new AngryDog();
    }

    @Bean
    public DogShelter dogShelter(){
        return new DogShelter();
    }

    @Bean
    public BeforeAllDogMethodsAspect beforeAngryDogBitesExample(){
        return new BeforeAllDogMethodsAspect();
    }
}

调用:

foo(){
        System.out.println("----------------");
        System.out.println("Getting a dog from locally created dog shelter. And playing with it");
        DogShelter locallyCreatedDogShelter = new DogShelter();
        AngryDog dogFromLocalShelter = locallyCreatedDogShelter.getAngryDog();
        dogFromLocalShelter.play();

        System.out.println("----------------");
        System.out.println("Getting a dog from autowired dog shelter. And playing with it");
        AngryDog dogFromAutoWiredDogShelter = autowiredDogShelter.getAngryDog();
        dogFromAutoWiredDogShelter.play();
}

输出:

 ----------------
 Getting a dog from locally created dog shelter. And playing with it
 AngryDog->play()
 AngryDog->bark()
 AngryDog->bite()
 ----------------
 Getting a dog from autowired dog shelter. And playing with it
 SpringAOP aspect called!
 AngryDog->play()
 AngryDog->bark()
 AngryDog->bite()

您应该在方面显示方法名称。否则,你不知道拦截了哪个方法。

关于您的问题:拦截的可能是 getAngryDog() 方法而不是 play() 方法。