IOC 原理
运行代码架构图

new ClassPathXmlApplicationContext("spring-ioc.xml");
ClassPathXmlApplicationContext(configLocation, new AutowireCapableBeanFactory());
AbstractApplicationContext.refresh();
ClassPathXmlApplicationContext.loadBeanDefinitions(beanFactory);
AbstractBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader();
beanDefinitionReader.loadBeanDefinitions(configLocation);
doLoadBeanDefinitions(inputStream);
processBeanDefinition(ele)
processProperty(ele, beanDefinition);
beanDefinition.setBeanClassName(className);
getRegistry().put(name, beanDefinition)
beanFactory.registerBeanDefinition
AbstractApplicationContext.registerBeanPostProcessors(AbstractBeanFactory beanFactory)
List beanPostProcessorList = beanFactory.getBeansForType(BeanPostProcessor.class)
beanFactory.addBeanPostProcessor((BeanPostProcessor)beanPostProcessor);
HelloService helloService = (HelloService)applicationContext.getBean("helloService")
AbstractApplicationContext.getBean(String name)
beanFactory.getBean(name)
BeanDefinition beanDefinition = beanDefinitionMap.get(name);
Object bean = beanDefinition.getBean();
bean = doCreateBean(beanDefinition);
Object bean = beanDefinition.getBeanClass().newInstance();
beanDefinition.setBean(bean);
AutowireCapableBeanFactory.applyPropertyValues(bean, beanDefinition);
bean = initializeBean(bean, name);
for (BeanPostProcessor beanPostProcessor : beanPostProcessors) {
bean = beanPostProcessor.postProcessBeforeInitialization(bean, name);
}
for (BeanPostProcessor beanPostProcessor : beanPostProcessors) {
bean = beanPostProcessor.postProcessAfterInitialization(bean, name);
}
1.BeanPostProcessor 后置处理器
BeanPostProcessor 是一个接口的定义,里面只有两个接口。
postProcessBeforeInitialization
postProcessAfterInitialization
后置处理器需要实现这个接口,并把该实现类加入到bean容器中。成为一个bean对象。
根据是否都继承自BeanPostProcessor.class isAssignableFrom 找出满足的bean对象。
放入beanPostProcessors的list列表中。
在bean创建成功之后,调用后置处理器initializeBean。循环执行里面的每一个后置处理器。
每个后置处理器需要把bean对象返回,否则通过getBean拿不到对象。
BeanDefinition beanDefinition = beanDefinitionMap.get(name);
if (beanDefinition == null) {
throw new Exception("No bean named " + name + " is defined");
}
Object bean = beanDefinition.getBean();
if (bean == null) {
bean = doCreateBean(beanDefinition);
bean = initializeBean(bean, name);
}
return bean;
2.spring 4.2.4版本后置处理器逻辑
在AbstractAutowireCapableBeanFactory class 中
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException
在doCreateBean方法中
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
mbd.postProcessed = true;
}
}
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
return getEarlyBeanReference(beanName, mbd, bean);
}
});
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}

before 与 after中间仅多了一个初始化方法init-method。
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
3.spring的singleton与prototype
当bean对象从xml读取到beanDefinition,若scope配置是空的,则在生成bean实例的时候,判断scope类型,若是原型,则是单例类型则生成对象。如果是空
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
@Override
public Boolean run() {
return ((SmartFactoryBean<?>) factory).isEagerInit();
}
}, getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
else {
getBean(beanName);
}
}
如上代码所示,getMergedLocalBeanDefinition会获取bean的定义信息。
若scope定义的时候为空,则有下面的逻辑处理。可见默认是单例模式。
// Set default singleton scope, if not configured before.
if (!StringUtils.hasLength(mbd.getScope())) {
mbd.setScope(RootBeanDefinition.SCOPE_SINGLETON);
}
spring模拟的代码参考 github.com/zhangjeff/s…
AOP 原理
先看下AOP的几个名词解释
1.通知Advice: 定义了在切入点pointcut里面定义的程序点具体要做的操作和处理,它通过before,after和around来区别是在每个切入点之前、之后还是代替执行的代码。
2.切入点Pointcut: 表示一组连接点joinpoint,这些连接点或是通过逻辑关系组合起来,或是通过通配、正则表达式等方式集中起来,它定义了相应的操作处理通知Advice将要发生的地方。
3.目标对象Target:代理的目标对象,即切面要被应用到的目标对象。
4.通知器Advisor:当完成对目标对象方法的增强行为操作(Advice)和切入点Point的设计开发之后,需要一个对象将目标对象、增强行为和切入点三者结合起来,通知器Advisor就是一个实现这个功能的对象,即通过Advisor通知器,可以定义哪些目标对象的哪些方法在什么地方使用这些增强行为。
AspectJAwareAdvisorAutoProxyCreator是Spring的BeanPostProcessor,一个后置处理器,所有的bean都会经过该后置处理器拦截,如果匹配Pointcut切面的则会返回代理类。代码如下。
public Object postProcessAfterInitialization(Object bean, String beanName) throws Exception {
if (bean instanceof AspectJExpressionPointcutAdvisor) {
return bean;
}
if (bean instanceof MethodInterceptor) {
return bean;
}
List<AspectJExpressionPointcutAdvisor> advisors = beanFactory
.getBeansForType(AspectJExpressionPointcutAdvisor.class);
for (AspectJExpressionPointcutAdvisor advisor : advisors) {
if (advisor.getPointcut().getClassFilter().matches(bean.getClass())) {
ProxyFactory advisedSupport = new ProxyFactory();
advisedSupport.setMethodInterceptor((MethodInterceptor) advisor.getAdvice());
advisedSupport.setMethodMatcher(advisor.getPointcut().getMethodMatcher());
TargetSource targetSource = new TargetSource(bean, bean.getClass(), bean.getClass().getInterfaces());
advisedSupport.setTargetSource(targetSource);
return advisedSupport.getProxy();
}
}
return bean;
}
Spring的Aop主要分为两种,CGLIB和jdk动态代理,动态代理都是在运行过程中生成出来的。
jdk动态代理采用的是反射机制实现接口的代理。在调用具体方法前调用InvokeHandler来处理。
看一个jdk动态代理的实例
接口
public interface Subject {
void rent();
void hello(String str);
}
实现类
public class RealSubject implements Subject {
@Override
public void rent() {
System.out.println("I want to rent my house");
}
@Override
public void hello(String str) {
System.out.println("hello: " + str);
}
}
实现InvokeHandler的实现类
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class DynamicProxy implements InvocationHandler {
private Object subject;
public DynamicProxy(Object subject) {
this.subject = subject;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before rent house");
System.out.println("Method:" + method);
method.invoke(subject, args);
System.out.println("after rent house");
return null;
}
}
客户端
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
public class Client {
public static void main(String[] args) {
System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
Subject realSubject = new RealSubject();
InvocationHandler handler = new DynamicProxy(realSubject);
Subject subject = (Subject) Proxy.newProxyInstance(handler.getClass().getClassLoader(), realSubject
.getClass().getInterfaces(), handler);
System.out.println(subject.getClass().getName());
subject.rent();
}
}
当设置属性“sun.misc.ProxyGenerator.saveGeneratedFiles”,设置为true的时候。 可以生成新生成的代理类$Proxy0。
public final class $Proxy0 extends Proxy implements Subject {
private static Method m1;
private static Method m4;
private static Method m2;
private static Method m3;
private static Method m0;
public $Proxy0(InvocationHandler var1) throws {
super(var1);
}
public final boolean equals(Object var1) throws {
try {
return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
public final void rent() throws {
try {
super.h.invoke(this, m4, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final String toString() throws {
try {
return (String)super.h.invoke(this, m2, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final void hello(String var1) throws {
try {
super.h.invoke(this, m3, new Object[]{var1});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
public final int hashCode() throws {
try {
return (Integer)super.h.invoke(this, m0, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
static {
try {
m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
m4 = Class.forName("com.jeff.jdkaopExample.Subject").getMethod("rent");
m2 = Class.forName("java.lang.Object").getMethod("toString");
m3 = Class.forName("com.jeff.jdkaopExample.Subject").getMethod("hello", Class.forName("java.lang.String"));
m0 = Class.forName("java.lang.Object").getMethod("hashCode");
} catch (NoSuchMethodException var2) {
throw new NoSuchMethodError(var2.getMessage());
} catch (ClassNotFoundException var3) {
throw new NoClassDefFoundError(var3.getMessage());
}
}
}
所以当调用真是的接口的时候,会调用到代理类$Proxy0的rent()接口,该接口的内容是super.h.invoke(this, m4, (Object[])null); 即调用proxy的h(InvocationHandler),该示例应该是 DynamicProxy实现,调用invoke方法,及调用DynamicProxy的invoke方法。

public Object invoke(Object proxy, Method method, Object[] args) 接口中第一个参数proxy的作用,一般情况下,没什么作用,从实际调用传入的参数可以看到,在生成的代理类中传入的是当前的代理类this,所以当调用方法,返回proxy的时候,实际返回的是代理对象,跟参数名称proxy含义一致。这种当在方法支持链式调用的时候可以进行链式调用。
CGLIB动态代理采用的是asm开源包,对代理类的class文件加载进来,通过修改其字节码生成子类来处理。
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(UserDaoImpl.class);
enhancer.setCallback(new MethodInterceptor(){
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("this is CGlib test");
return proxy.invokeSuper(obj, args);
}
});
UserDaoImpl userDao = (UserDaoImpl)enhancer.create();
userDao.query("张三");
如上代码是CGLIB的核心,调用的是enhance增强。callback的函数需要实现MethodInterceptor接口。
Spring bean循环依赖
当Spring有两个bean相互依赖的时候,没有一个bean在产生的时候能走完一个完整的生命周期。所以需要bean在完成完整的生命周期之前暴露bean的对象,否则就会形成死循环。暴露的不是一个半成品的bean,而是一个bean工厂,可以继续完成bean的postprossess等后置处理器。
暴露一个工厂的目的是为了提供一个完整的bean,真实调用的时候,工厂返回bean的时候会把这个bean的后置处置器都完整的执行。 "getEarlyBeanReference",他的javadoc是,尤其是为解决循环依赖的。
Obtain a reference for early access to the specified bean, typically for the purpose of resolving a circular reference.
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
if (bean != null && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
if (exposedObject == null) {
return exposedObject;
}
}
}
}
return exposedObject;
}

// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
return getEarlyBeanReference(beanName, mbd, bean);
}
});
}
调用的地方
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
protected void beforeSingletonCreation(String beanName) {
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
}
spring的三级缓存,也就是三个Map集合类: singletonObjects:第一级缓存,里面放置的是实例化好的单例对象; earlySingletonObjects:第二级缓存,里面存放的是提前曝光的单例对象; singletonFactories:第三级缓存,里面存放的是要被实例化的对象的对象工厂。 所以当一个Bean调用构造函数进行实例化后,即使属性还未填充,就可以通过三级缓存向外暴露依赖的引用值(所以循环依赖问题的解决也是基于Java的引用传递),这也说明了另外一点,基于构造函数的注入,如果有循环依赖,Spring是不能够解决的。还要说明一点,Spring默认的Bean Scope是单例的,而三级缓存中都包含singleton,可见是对于单例Bean之间的循环依赖的解决,Spring是通过三级缓存来实现的。
spring的aware接口的支持
当bean继承接口ApplicationContextAware的时候,对应的bean是可以拿到applicationContext
实现原理
1.在AbstractApplicationContext.refresh()方法中当运行到


ApplicationContextAwareProcessor是一个bean的后置处理器,在bean被初始化后,就会实现该后置处理器。
public ApplicationContextAwareProcessor(ConfigurableApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
刚才已经把applicationContext给放置到了该后置处理器。
postProcessBeforeInitialization中
invokeAwareInterfaces(bean);
if (bean instanceof ApplicationContextAware) {
((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
}
通过以上步骤,只要bean继承了ApplicationContextAware 就能获取到applicationContext。
Spring的annotation实现
核心逻辑是AnnotationConfigApplicationContext 是其中的一种applicationContext的实现,会扫描提供的文件夹的文件,然后根据文件夹里面文件内容,再判断里面的类型,读取之后放到BeanDefinition中,放在BeanDefinitionHolder中,最后把该内容注册到beanFactory中,之后的逻辑就与xml的一致了。
@Component,@Service,@Repository,@Controller区别, @Component是一个通用的标签。当判断需要注入的时候,判断标签是否引用了@Component 标签。



其他几种类似。

spring源码中判断标签是否含有元标签Component,还有的才会加入到BeanDefinition中。
FactoryBean的作用
Spring中有两种类型的Bean,一种是普通的Bean,另一种是工厂Bean。即FactoryBean。FactoryBean跟普通的Bean不同,其返回的对象不是指定一个实例,而是该FactoryBean的getObject方法所返回的对象。
一般情况下,Spring通过反射机制,利用bean的class属性指定实现类的实例化Bean,在某些情况下,实例化Bean的过程比较复杂,如果按照传统的方式,则需要再bean中提供大量的配置信息。配置方式的灵活性是受限的,这时采用编码的方式可能会得到一个简单的方案。Spring为此提供了一个FactoryBean的工厂类接口,可以通过实现该接口定制实例化Bean的逻辑。FactoryBean对spring框架来说占用重要的地位,它隐藏了实例化的一些复杂的bean的细节,给上层应用带来了便利。
很多开源项目在集成Spring 时都使用到FactoryBean,比如 MyBatis3 提供 mybatis-spring项目中的 org.mybatis.spring.SqlSessionFactoryBean:

如上图所示,普通的bean,走到红框的位置的时候,就返回了。FactoryBean会继续向下,调用当前bean的Object方法。

spring的观察者模式,发布-订阅。
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
AbstractApplicationContext中 refresh() -> initApplicationEventMulticaster();中作用
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
if (logger.isDebugEnabled()) {
logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
}
else {
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
if (logger.isDebugEnabled()) {
logger.debug("Unable to locate ApplicationEventMulticaster with name '" +
APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
"': using default [" + this.applicationEventMulticaster + "]");
}
}
}
Initialize the ApplicationEventMulticaster.
Uses SimpleApplicationEventMulticaster if none defined in the context.
从注释上也可以看出,如果自定义了applicationEventMulticaster的实现类,则直接用自定义
的,否则用默认的实现SimpleApplicationEventMulticaster,默认的且在工厂中注册为单例的。
####### SimpleApplicationEventMulticaster中关于开启异步线程池,防止个别通知耗时太长,堵塞线程。
By default, all listeners are invoked in the calling thread. This allows the danger of a
rogue listener blocking the entire application, but adds minimal overhead.
Specify an alternative task executor to have listeners executed in different
threads, for example from a thread pool
可以根据上面的方式,自定义实现applicationEventMulticaster的实现bean。实现方式如下:
@Configuration
public class AsyncEventConfig implements BeanFactoryAware {
private BeanFactory beanFactory;
@Bean(name = "applicationEventMulticaster")
public ApplicationEventMulticaster simpleApplicationEventMulticaster() {
SimpleApplicationEventMulticaster eventMulticaster
= new SimpleApplicationEventMulticaster(beanFactory);
eventMulticaster.setTaskExecutor(new SimpleAsyncTaskExecutor());
return eventMulticaster;
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
}
ApplicationListener监听器都需要实现这个接口,其中有一个方法onApplicationEvent。
void onApplicationEvent(E event)
当多播器调用的时候,会根据类型筛选,然后调用监听者的onApplicationEvent方法。