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() 方法。
我是 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() 方法。