我对于spring的认识:
其实之前本着 兴趣好奇的心态来钻研spring源码,到现在每天都会渗透spring的一些内容,发现越是研究越是觉得spring是java 开发难得的框架,其设计理念以及使用上都是十分前沿,更何况现在也一直不断迭代更新中。
使用过spring 框架的开发人员,不难发现spring主要有两大法宝,Ioc以及aop。 IOC 其实是包含着两层含义,控制反转以及依赖注入。 控制反转的含义即使我要 把我想要的东西,也就是对象交给spring容器替我保管(其实就是把spring 当作工厂,随时可以new 出对象,可以看到spirng 有个接口,beanFactory 可以说是统筹全局,所有的对象产出都是在围绕他),只是负责生产对象。而依赖注入呢,他的使用就是我要从spring取出对象来有我所用(大家应该对autowire/resourse注解很熟悉把,没错,他就是目的就是从Spring 获取到的对象赋给他来使用)。我相信大家看到这里就应该很明白Spirng 的目的了把。
我想这就是spring最初的设计理念,但是他的实现方式还是相对来说是比较复杂的。 他需要包涵各种场景,打个比方,如果用户想通过编程式实现对象的注入,那么spring 可以通过编程直接将对象注入到Spring中,如下:
DefaultListableBeanFactory defaultListableBeanFactory = new DefaultListableBeanFactory();
RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(User.class);
defaultListableBeanFactory.registerBeanDefinition("user", rootBeanDefinition);
User bean = (User)defaultListableBeanFactory.getBean("user");
bean.setUserName("sp");
System.out.println("用户姓名是:"+bean.getUserName());
如果我想通过xml 方式注入到spring中,也很简单,我定义一个xml 文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="user" class="test.User">
<property name="userName" value="sp"> </property>
</bean>
</beans>
代码如下:
@Test
public void xmlAutowireSpring() {
DefaultListableBeanFactory defaultListableBeanFactory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(defaultListableBeanFactory);
xmlBeanDefinitionReader.loadBeanDefinitions("user.xml");
User bean = (User)defaultListableBeanFactory.getBean("user");
System.out.println("用户姓名是"+bean.getUserName());
}
那我又想通过properties 文件来注入我想要的对象,不用慌,也是按照当前的Spring流程来进行处理:
定义一个user.properties文件,内容如下:
user.(class)=test.User
user.userName=sp112
对应的java代码:
@Test
public void propertiesAutowireSpring() {
DefaultListableBeanFactory defaultListableBeanFactory = new DefaultListableBeanFactory();
PropertiesBeanDefinitionReader propertiesBeanDefinitionReader = new PropertiesBeanDefinitionReader(defaultListableBeanFactory);
propertiesBeanDefinitionReader.loadBeanDefinitions("user.properties");
User bean = (User)defaultListableBeanFactory.getBean("user");
System.out.println("用户姓名是"+bean.getUserName());
}
到这里,是不是觉得Spring 使用起来非常便利,可以通过N种方式来满足你的使用,具体实现方式还是针对具体业务。其实你不难发现,这三种实现方式我统统用了DefaultListableBeanFactory 这个类来实现的,我们可以看看这个类具体包含哪些东西。
@SuppressWarnings("serial")
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory(负责对象的实例化以及初始化)
implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
AbstractAutowireCapableBeanFactory这个类承担了创建bean以及获取bean 的工作,主要方法有:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(String, RootBeanDefinition, Object[]);
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
if (logger.isDebugEnabled()) {
logger.debug("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// Make sure bean class is actually resolved at this point, and
// clone the bean definition in case of a dynamically resolved Class
// which cannot be stored in the shared merged bean definition.
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
//这里才是真正创建bean的方法(do 就是我要干了)
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
接下来我们来看下1、org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(String, RootBeanDefinition, Object[]);我重点把重要的方法截取下。
BeanWrapper instanceWrapper = null;
if (instanceWrapper == null) {
·············//创建包装类,这个类在注入属性值有承上启下的作用,同时对象的实例也会放 ·············在这里。
//beanName: 实例化对象的唯一识别;
//mdb:RootBeanDefinition这个对象主要负责对相关实例的属性以及对象的填充。
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
2、org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(String, RootBeanDefinition, BeanWrapper);
Object exposedObject = bean;
try {
//初始化对象,将上述实例化的对象进行赋值操作
populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
}
这就是Spring IOC的原理,其实好多细节都没有整理出来,单只要顺着以上的思路跟踪源码,慢慢的你就会对Spring 豁然开朗。