《5.1.2 spring-IOC容器篇–ApplicationContext》末尾:ApplicationContext中的refresh方法
《5.1.3 Spring-IOC容器篇–BeanDefinition》
12:42前后 : customizeBeanFactory(beanFacotry)
《5.1.4 Spring-IOC容器篇–bean的生命周期》
34:35左右:prototype的bean不能被注入?我的实践表明:不准确。详见5.1.9我的笔记
《5.1.5 SpringAOP思想》
18:29 spring的aop有Cglib和jdk动态代理两种实现方式,默认为jdk动态代理。我的debugger实验结果表明,如果被代理的是接口,则使用jdk动态代理,否则使用Cglib动态代理。
发现用Cglib代理的对象,对其调用getClass方法没有增强效果。原因应是getClass方法被final修饰
《5.1.6 SpringAOP源码流程》
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
AspectJAutoProxyRegistrar的源码注释中提到Registers an AnnotationAwareAspectJAutoProxyCreator。这里的AnnotationAwareAspectJAutoProxyCreator是BeanPostProcessor的一个子类。又如org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator是BeanPostProcessor的一个子类,aop在其postProcessAfterInitialization方法中实现。
22:19 : 关键代码:
我的简单概括:@EnableAspectJAutoProxy开启了一个BeanPostProcessor,在这个BeanPostProcessor的postProcessAfterInitialization方法中,用jdk动态代理或者Cglib动态代理的方式,实现了aop
《5.1.7 事务的概念》:6:36 : spring默认的事务传播机制:PROPAGATION_REQUIRED
太难了~面试官让我结合案例讲讲自己对Spring事务传播行为的理解中结合实例理解:
在外围方法开启事务的情况下Propagation.REQUIRED修饰的内部方法会加入到外围方法的事务中,所有Propagation.REQUIRED修饰的内部方法和外围方法均属于同一事务,只要一个方法回滚,整个事务均回滚。
在外围方法未开启事务的情况下Propagation.REQUIRES_NEW修饰的内部方法会新开启自己的事务,且开启的事务相互独立,互不干扰。
在外围方法开启事务的情况下Propagation.NESTED修饰的内部方法属于外部事务的子事务,外围主事务回滚,子事务一定回滚,而内部子事务可以单独回滚而不影响外围主事务和其他子事务
《5.1.8 事务源码》https://www.javazhiyin.com/35497.html
《5.1.9 Spring问题域&核心流程分析》
- 循环依赖
- 28:11 depends-on
- 我的实践表示,prototype的bean之间的循环依赖会抛异常。prototype的bean可以被注入。代码如下。而如果通过注释property标签等手段破坏循环依赖,或者至少将其中一个的scope转为单例,都不会报错
applicationContext.xml:
<bean id="b" class="com.study.ioc.basic.B" scope="prototype">
<property name="a" ref="a"></property>
</bean>
<bean id="a" class="com.study.ioc.basic.A" scope="prototype">
<property name="b" ref="b"></property>
</bean>
类A:
public class A {
private B b;
public A(){
System.out.println("a created:"+this);
}
public B getB() {
return b;
}
public void setB(B b) {
this.b = b;
System.out.println("setB:"+b+" in a");
}
}
类B:
public class B {
private A a;
public B() {
System.out.println("b created:"+this);
}
public A getA() {
return a;
}
public void setA(A a) {
this.a = a;
System.out.println("setA:"+a+" in b");
}
}
main函数:
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
context.getBean("a");
报错如下:
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'a' defined in class path resource [applicationContext.xml]: Cannot resolve reference to bean 'b' while setting bean property 'b'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'b' defined in class path resource [applicationContext.xml]: Cannot resolve reference to bean 'a' while setting bean property 'a'; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'a': Requested bean is currently in creation: Is there an unresolvable circular reference?
- 104:26+ 依赖循环的流程,以及三级缓存
- 119:37 禁止依赖循环。若有依赖循环会报错
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
context.setAllowCircularReferences(false);
context.refresh();
- 122:55 BeanFactoryPostProcessor是在spring容器加载了bean的定义文件之后,在bean实例化之前执行的
- The PostConstruct annotation is used on a method that needs to be executed after dependency injection is done
@PostConstruct
public void init() {