下面是我写的一段Spring AOP的代码,在分析的时候发现有些问题弄不清楚,求高手解释:
1、切面,拦截doing()方法:
@Aspect
@Component
public class B {
@Pointcut("execution(* doing(..))")
public void pointCutMethod(){
}
@Before("pointCutMethod()")
public void doBefore(){
System.out.println("前置通知!");
}
@After("pointCutMethod()")
public void doAfter(){
System.out.println("后置通知!");
}
}
2、普通业务逻辑类
@Component
public class AImpl implements A
{
public void doing() {
System.out.println("hello");
}
public static void main( String[] args )
{
ApplicationContext ctx=new ClassPathXmlApplicationContext("bean.xml");
AImpl a=ctx.getBean(AImpl.class); //(1)出错行
//A a=ctx.getBean(A.class); //(2)换成这样就正确了
a.doing();
}
}
使用行(1)的话,会报错:
NoSuchBeanDefinitionException:No qualifying bean of type [com.lcl.springlearning.AImpl] is defined。
疑问如下:
1、spring AOP的动态代理是发生在 AImpl a=ctx.getBean(AImpl.class); 的时候吗,还是发生在a.doing();的时候?换句话说,spring AOP是通过ctx.getBean(AImpl.class)返回一个代理对象的方式来代理,还是定义的切面拦截了doing()方法,然后生成代理对象执行的方式来代理?
2、如果第一种情况正确,那么ApplicationContext 怎么知道哪个对象需要代理,然后返回代理对象?
3、如果第二种情况正确,那么为什么行(1)会报错?
------解决思路----------------------
spring的根基是工厂
从工厂创建对像的时候,就确定了是原对像或是代理类对像,
创建对像的根据是各种配置文件和注解,
spring初始化的时候,先读到所有配置信息,拿到对像之间的依赖关系,代理关系等, 这是工厂创建对像的依据, 换句话说,spring初始化结束,对像关系就确定了,是否代理也确定的
3、如果第二种情况正确,那么为什么行(1)会报错?
spring的代理方式有两种,基于JDK的动态代理,还有个CGLIB.
到底用哪个形式决定于这个类是否实现了某个接口, 有接口的类实际上的类就是你写的这个类了,是动态代理类,随机命名的,用你的实现类Class肯定拿不出来
再有,需要手动getBean的情况下,你这最好给它起个名字 @Component("xxxx")