Spring 是如何默认开启循环依赖的?如何关闭支持循环依赖?
@Autowired和@Resource区别
@Autowired由AutowiredAnnotationBeanPostProcessor后置处理器解析,@Resource由CommonAnnotationBeanPostProcessor解析
循环依赖的实现
/** Cache of singleton objects: bean name to bean instance. */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
/** Cache of singleton factories: bean name to ObjectFactory. */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
/** Cache of early singleton objects: bean name to bean instance. */
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);singletonObjects 单例池 Spring容器 一级缓存 存储的是bean
singletonFactories 工厂 二级缓存 存储的是对象(半成品的bean)
earlySingletonObjects 三级缓存
三级缓存put一个从二级缓存中生产出来的一个对象
为什么需要三级缓存?因为防止重复创建,提高效率
Spring的生命周期
new
init 生命周期的初始方法 @PostConstruct
注入
代理 aop
put singletonObjects
Spring的refresh()
prepareRefresh() refresh前的预处理
// Prepare this context for refreshing.
prepareRefresh();initPropertySources() 初始化一些属性设置;子类自定义个性化的属性设置方法;
getEnvironment().validateRequireProperties() 检验属性的合法等;
earlyApplicationEvents = new LinkedHashSet<>(); 保存容器中的一些早期事件;
获取BeanFactory
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
return getBeanFactory();
}- refreshBeanFactory(); 刷新(创建)BeanFactory;
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}
protected final void refreshBeanFactory() throws IllegalStateException {
if (!this.refreshed.compareAndSet(false, true)) {
throw new IllegalStateException(
"GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");
}
// 设置id
this.beanFactory.setSerializationId(getId());
}getBeanFactory(); 返回刚才GenericApplicationContext创建的BeanFactory对象;
将创建的BeanFactory(DefaultListableBeanFactory)对象;
prepareBeanFactory(beanFactory); BeanFactory的预准备工作(BeanFactory的一些设置)
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader etc.
// 1. 设置BeanFactory的类加载器、支持表达式解析器等
beanFactory.setBeanClassLoader(getClassLoader());
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// Configure the bean factory with context callbacks.
// 2. 添加部分BeanPostProcessor【ApplicationContextAwareProcessor】
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
// 3. 设置忽略的自动装配的接口 beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
// BeanFactory interface not registered as resolvable type in a plain factory.
// MessageSource registered (and found for autowiring) as a bean.
// 4. 注册可以解析的自动装配(直接在任何组件中自动注入)
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// Register early post-processor for detecting inner beans as ApplicationListeners.
// 5. 添加BeanPostProcessor【ApplicationListenerDetector】
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// Detect a LoadTimeWeaver and prepare for weaving, if found.
// 6. 添加编译时的AspectJ
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
// Set a temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
// Register default environment beans.
// 7. 给BeanFactory注册一些能用的组件
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
}// Allows post-processing of the bean factory in context subclasses. postProcessBeanFactory(beanFactory);
3) 再注册Ordered接口的; 4) 最后注册没有实现任何优先级接口的; 5) 最终注册MergedBeanDefinitionPostProcessor; 6) 注册一个ApplicationListenerDetector; 在Bean创建完成后检查是否是ApplicationListener,如果是,则 applicationContext.addApplicationListener((ApplicationListener<?>) bean);
BeanFactory准备工作完成后进行的后置处理工作;
子类通过重写这个方法在BeanFactory创建并预准备完成以后做进一步的设置;
=========以上是BeanFactory的创建及预准备工作=========
+ invokeBeanFactoryPostProcessors(beanFactory); 执行BeanFactoryPostProcessor
BeanFactoryPostProcessor:BeanFactory的后置处理器,在BeanFactory标准初始化之后执行;
两个接口:BeanFactoryPostProcessor,BeanDefinitionRegistryPostProcessor;
先执行BeanDefinitionRegistryPostProcessor:
1) 获取所有的BeanDefinitionRegistryPostProcessor;
2) 先执行实现了PriorityOrdered优先级接口的BeanDefinitionRegistryPostProcessor
postProcessor.postProcessBeanDefinitionRegistry(registry);
3) 再执行实现了Ordered顺序接口的BeanDefinitionRegistryPostProcessor
postProcessor.postProcessBeanDefinitionRegistry(registry);
4) 最后执行没有实现任何优先级或顺序接口的BeanDefinitionRegistryPostProcessor
postProcessor.postProcessBeanDefinitionRegistry(registry);
再执行beanFactoryPostProcessor的方法:
1) 获取所有的BeanFactoryPostProcessor;
2) 先执行实现了PriorityOrdered优先级接口的BeanFactoryPostProcessor
postProcessor.postProcessBeanFactory(beanFactory);
3) 再执行实现了Ordered顺序接口的BeanFactoryPostProcessor
postProcessor.postProcessBeanFactory(beanFactory);
4) 最后执行没有实现任何优先级或顺序接口的BeanFactoryPostProcessor
postProcessor.postProcessBeanFactory(beanFactory);
+ registerBeanPostProcessors(beanFactory);注册BeanPostProcessor【Bean的后置处理器,拦截bean的创建过程】
不同接口类型的BeanPostProcessor在Bean创建前后的执行时机是不一样的:
BeanPostProcessor
InstantiationAwareBeanPostProcessor
DestructionAwareBeanPostProcessor
SmartInstantiationAwareBeanPostProcessor
MergedBeanDefinitionPostProcessor【internalPostProcessors】
1) 获取所有的BeanPostProcessor;(后置处理器都可以通过PriorityOrdered、Ordered接口来执行优先级)
2) 先注册PriorityOrdered优先级接口的BeanPostProcessor
把每一个BeanPostProcessor添加到Beanfactory中
```java
/**
* Register the given BeanPostProcessor beans.
*/
private static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {
for (BeanPostProcessor postProcessor : postProcessors) {
beanFactory.addBeanPostProcessor(postProcessor);
}
}// Re-register post-processor for detecting inner beans as ApplicationListeners,
// moving it to the end of the processor chain (for picking up proxies etc).
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));initMessageSource(); 初始化MessageSource组件(做国际化功能,消息绑定,消息解析)
获取BeanFactory;
看容器中是否有id为messageSource,类型为MessageSource的组件;
若有则赋值给messageSource,若没有则new DelegatingMessageSource();
MessageSource:取出国际化配置文件中的某个key值(能按照区域信息获取);
- 把创建好的MessageSource注册在容器中,以后获取国际化配置文件的值时,可以自动注入MessageSource;
beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
MessageSource.getMessage(String code, @Nullable Object[] args, Locale locale)
initApplicationEventMulticaster(); 初始化事件派发器
获取BeanFactory;
从BeanFactory中获取applicationEventMulticaster的ApplicationEventMulticaster;
如果上一步没有配置,则创建 new SimpleApplicationEventMulticaster(beanFactory);
将创建的ApplicationEventMulticaster添加到BeanFactory中,以后其他组件直接自动注入;
onRefresh(); 留给子容器(子类)
子类重写这个方法,在容器刷新时可以自定义逻辑;
registerListeners(); 将容器中所有项目里面的ApplicationListener注册进来
- 从容器中拿到所有的ApplicationListener
2) 将每个监听器添加到事件派发器中
// Register statically specified listeners first.
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}- 派发之前步骤产生的事件
finishBeanFactoryInitialization(beanFactory); 初始化所有剩下的单实例bean
beanFactory.preInstantiateSingletons();
获取容器中的所有Bean,依次进行初始化和创建对象
获取Bean的定义信息:RootBeanDefinition
Bean不是抽象的,是单实例的,不是懒加载的:
1) 判断是否是FactoryBean:是否是实现FactoryBean接口的Bean;
2) 不是FactoryBean,利用getBean(beanName);创建对象;
doGetBean(name, null, null, false);
- 先获取缓存中保存的单实例Bean,如果能获取到说明这个Bean之前被创建过(所有创建过的单实例Bean都会被缓存起来);
从private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256); 中获取
缓存中获取不到,开始Bean的创建对象流程;
标记当前bean已经被创建;
获取Bean的定义信息;
获取当前Bean依赖的其他Bean,若有 则按照getBean()把依赖的Bean先创建出来;
启动单实例Bean的创建流程;
1) createBean(beanName, mbd, args);
2) Object bean = resolveBeforeInstantiation(beanName, mbdToUse); 让BeanPostProcessor先拦截返回代理对象
InstantiationAwareBeanPostProcessor 提前执行
先触发postProcessBeforeInstantiation();
如果有返回值,触发postProcessAfterInitialization();
3) 如果前面的InstantiationAwareBeanPostProcessor 没有返回代理对象,则执行4);
4) Object beanInstance = doCreateBean(beanName, mbdToUse, args); 创建Bean
1) 创建Bean实例:createBeanInstance(beanName, mbd, args);
利用工厂方法或者对象的构造器创建出Bean实例;
2) applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
调用MergedBeanDefinitionPostProcessor 的postProcessMergedBeanDefinition(mbd, beanType, beanName);
3) 【Bean属性赋值】populateBean(beanName, mbd, instanceWrapper);
赋值之前:
1) 拿到InstantiationAwareBeanPostProcessor后置处理器:postProcessAfterInstantiation();
2) 拿到InstantiationAwareBeanPostProcessor后置处理器:postProcessPropertyValues();
赋值:
3) 应用Bean属性的值,为属性利用setter方法等进行赋值:applyPropertyValues(beanName, mbd, bw, pvs);
4) 【Bean初始化】exposedObject = initializeBean(beanName, exposedObject, mbd);
1) 【执行Aware接口方法】invokeAwareMethods(beanName, bean); 执行xxxAware的方法;BeanNameAware/BeanClassLoaderAware/BeanFactoryAware
2) 【执行后置处理器初始化之前】applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
BeanPostProcessor.postProcessBeforeInitialization();
3) 【执行初始化方法】invokeInitMethods(beanName, wrappedBean, mbd);
1) 是否是InitializingBean接口的实现,执行接口规定的初始化;
2) 是否自定义初始化;
4) 【执行后置处理器初始化之后】applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); BeanPostProcessor.postProcessAfterInitialization()
5) 注册Bean的销毁方法registerDisposableBeanIfNecessary(beanName, bean, mbd);
5) 将创建的Bean添加到缓存中SingletonObjects;
IOC容器就是这些Map,很多的Map里面保存了Bean和环境信息等;
所有Bean都利用getBean创建完成之后,检查所有的Bean是否是SmartInitializingSingleton接口的,如果是执行afterSingletonsInstantiated();
finishRefresh(); 完成BeanFactory的初始化创建工作,IOC容器就创建完成
// Clear context-level resource caches (such as ASM metadata from scanning).
clearResourceCaches();
// Initialize lifecycle processor for this context.
// 初始化和生命周期有关的后置处理器LifecycleProcessor,默认从容器中找是否有LifecycleProcessor的组件,
// 如果没有new DefaultLifecycleProcessor();加入到容器
initLifecycleProcessor();
// Propagate refresh to lifecycle processor first.
// 拿到前面定义的生命周期处理器,回调onRefresh()
getLifecycleProcessor().onRefresh();
// Publish the final event.
// 发布容器刷新完成事件
publishEvent(new ContextRefreshedEvent(this));
// Participate in LiveBeansView MBean, if active.
LiveBeansView.registerApplicationContext(this);
总结:
1)Spring容器在启动时,会先保存所有注册进来的Bean的定义信息
1)xml注册bean:
2)注解注册bean
2)Spring容器在合适的时机创建这些Bean
1)用到这个Bean的时候:利用getBean创建bean,创建好以后保存在容器中;
2)统一创建剩下所有的bean时,finishBeanFactoryInitialization()
3)后置处理器:BeanPostProcessor
每个bean创建完成时,都会使用各种后置处理器进行处理,来增强bean的功能;
AutowiredAnnotationBeanPostProcessor:处理自动注入;
AnnotationAwareAspectJAutoProxyCreator:来做AOP功能
…
4)事件驱动模型
ApplicationListener:事件监听
ApplicationEventMulticaster:事件派发
依赖注入
构造器注入(默认无参构造)
set注入
@autowired
Spring 常用注解
组件类注解:
@Component :标准一个普通的spring Bean类。
@Repository:标注一个DAO组件类。
@Service:标注一个业务逻辑组件类。
@Controller:标注一个控制器组件类。
装配bean时常用的注解:
@Autowired:属于Spring 的org.springframework.beans.factory.annotation包下,可用于为类的属性、构造器、方法进行注值;
@Resource:不属于spring的注解,而是来自于JSR-250位于java.annotation包下,使用该annotation为目标bean指定协作者Bean。
@PostConstruct 和 @PreDestroy 方法 实现初始化和销毁bean之前进行的操作;
SpringMVC常用的注解
@Controller :表明该类会作为与前端作交互的控制层组件,通过服务接口定义的提供访问应用程序的一种行为,解释用户的输入,将其转换成一个模型然后将试图呈献给用户。
@RequestMapping : 这个注解用于将url映射到整个处理类或者特定的处理请求的方法。可以只用通配符;
@RequestParam :将请求的参数绑定到方法中的参数上,有required参数,默认情况下,required=true,也就是改参数必须要传。如果改参数可以传可不传,可以配置required=false。
@PathVariable : 该注解用于方法修饰方法参数,会将修饰的方法参数变为可供使用的uri变量(可用于动态绑定)。
@RequestBody : @RequestBody是指方法参数应该被绑定到HTTP请求Body上。
@ResponseBody : @ResponseBody与@RequestBody类似,它的作用是将返回类型直接输入到HTTP response body中。@ResponseBody在输出JSON格式的数据时,会经常用到。
AOP
通配符:
*匹配任意数量的字符
+匹配指定类及其子类
..一般用于匹配任意数的子包或参数
原理
织入的时机
- 编译期(AspectJ)
- 类加载时(AspectJ 5+)
- 运行时(Spring AOP)
动态代理
实现:基于接口代理,基于继承代理
JDK动态代理
类:java.lang.reflect.Proxy
接口:InvocationHandler
只能基于接口进行动态代理
cglib动态代理
区别
JDK只能针对有接口的类的接口方法进行动态代理,jdk也不能对private方法进行动态代理
cglib基于继承来实现代理,无法对static,final类进行代理,无法对private,static方法进行代理
JDK动态代理使用Java原生的反射API进行操作,在生成类上比较高效;CGLIB使用ASM框架直接对字节码进行操作,在类的执行过程中比较高效;
在Spring中的实现:
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: " +
"Either an interface or a target is required for proxy creation.");
}
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
...
}如果目标对象实现了接口,则默认采用JDK动态代理,否则采用cglib动态代理;
如果目标对象实现了接口,且强制cglib代理,则使用cglib动态代理;
强制使用cglib动态代理:@EnableAspectJAutoProxy(proxyTargetClass = true)
多个AOP如何叠加?
责任链模式
public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Cloneable {
...
public Object proceed() throws Throwable {
// We start with an index of -1 and increment early.
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
// Evaluate dynamic method matcher here: static part will already have
// been evaluated and found to match.
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
}
else {
// Dynamic matching failed.
// Skip this interceptor and invoke the next in the chain.
return proceed();
}
}
else {
// It's an interceptor, so we just invoke it: The pointcut will have
// been evaluated statically before this object was constructed.
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
...
}