Spring到底给我们带来什么

我对于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 豁然开朗。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值