IoC小结

本文围绕Spring框架展开,介绍了ClassLoader的重要方法、类装载过程及全盘委托机制,阐述Java反射机制及利用其实例化Bean和建立依赖关系。还详细讲解了BeanFactory中Bean的生命周期,以及Resource接口、ApplicationContext工作流程等,提及Spring组件分类和相关策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

内容来自《精通Spring4.X企业应用开发实战》

通过Java反射机制初始化一个类


public class demo1 {
	public static void main(String [] args) throws Throwable {
		User user = initByDefaultConst();		
		System.out.println(user.toString());
	}	
	public static User initByDefaultConst() throws Throwable {
	   //获取当前线程的ClassLoader。
	   ClassLoader loader = Thread.currentThread().getContextClassLoader();
	   //根据类的全限定名装载User类的反射实例Class。
	   Class clazz = loader.loadClass("com.jun.IoC.reflect.User");
	   //通过User的反射对象,获取User的构造函数对象Constructor。
	   Constructor cons = clazz.getDeclaredConstructor((Class[])null);
	   //通过构造函数对象的newInstance()方法实例化User,newInstance等于new。 
	   User user = (User)cons.newInstance();
	   //通过User的反射实例的getMethod方法获的属性的set方法。
	   Method setId =clazz.getMethod("setId", int.class);
	   setId.invoke(user, 1);
	   Method setName= clazz.getMethod("setName", String.class);
	   setName.invoke(user, "小明");
	   Method setPass= clazz.getMethod("setPass", String.class);
	   setPass.invoke(user, "123456");
	   Method setAddress= clazz.getMethod("setAddress", String.class);
	   setAddress.invoke(user, "安徽");
		return user;								
	}	
}

Class文件由类装载器装载后,在JVM中形成一份描述Class结构的元信息对象,通过该对象获知Class的结构信息

 

ClassLoader

ClassLoader是一个抽象类,位于java.lang包下。
ClassLoader重要方法

  • Class loadClass(String name)
    传入全限定类名,装载类。
  • Class defineClass(String name,byte[] b,int off,int len)
    将类文件的字节数组转成JVM内部的java.lang.Class对象。name为字节数组对应的类的全限定名。
  • Class findSystemClass(String name)
    从本地文件系统载入Class文件,本地文件系统不存在该Class文件,则抛出ClassNotFoundException异常。
  • Class findLoadedClass(String name)
    查看是否装入某个类,返回java.lang.Class对象,否则返回null。
  • ClassLoader getParent()
    获取装载器的父类装载器。

类装载器把类装入JVM中需经过
1.装载:查找和导入Class文件。
2.链接:校验、准备、解析。
3.初始化:对类的静态变量、静态代码块执行初始化工作。
JVM运行时产生三个ClassLoader
根装载器:C++编写,负责装载JRE的核心类库。
ExtClassLoader(扩展类装载器):负责装载JRE扩展目录ext中的jar包类。
AppClassLoader(应用类装载器):装载Classpath(根路径)路径下的类包。
根装载器是ExtClassLoader、APPClassLoader的父类。
全盘委托机制
先委托父类装载器寻找目标类,只有找不到时才从自己的类路径中查找并装载目标类。

Java反射机制

从Class对象中获取构造函数、成员变量、方法类等类元素的反射对象,以编程方式通过这些反射对象对目标类对象进行操作。
这些反射类在java.lang.reflect包中定义。

  • Constructor
    类的构造函数反射类,通过getConstructor()方法获取类的所有构造函数反射对象数组。
  • Method
    类的方法反射类,通过getDeclaredMethod()方法获取类的所有方法反射类对象数组Method[]。
  • Field
    类的成员变量的反射类,通过getDeclaredFields()方法获取类的成员变量反射对象数组。

Java的反射功能实例化Bean并建立Bean之间的依赖关系。

提供了Bean实例化缓存,Bean的生命周期管理,Bean实例代理,时间发布,资源装载等。
BeanFactory为IoC容器ApplicationContext为应用上下文。BeanFactory面向Spring,Spring的框架的基础设施。
ApplicationContext面向Spring框架的使用者,ApplicationContext建立在BeanFactory基础上,也称为Spring容器。

BeanFactory是个FactoryIOC容器或对象工厂,FactoryBean是个Bean。
FactoryBean本身是工厂存在于beanFactory之中创建。

BeanFactory 中 Bean 的生命周期

1.通过getBean(beanName) 向容器请求一个Bean时调用InstantiationAwareBeanPostProcessor接口的 postProcessBeforeInstantiation() 方法。
2.根据配置情况调用构造函数或工厂方法实例化Bean。
3.调用InstantiationAwareBeanPostProcessor接口的 postProcessAfterInstantiation() 方法,对已实例化的Bean进行处理。
4.配置属性信息之前需要调用InstantiationAwareBeanPostProcessor接口的 postProcessPropertyValues() 方法。
5.调用Bean的属性设置方法设置属性值。
6.调用BeanNameAware的 setBeanName()方法,将配置文件的Bean对应的名字设置到Bean中。
7.调用BeanFactoryAware的setBeanFactory()将BeanFactory容器实例设置到Bean中。
*8.调用BeanPostProcessor的postProcessBeforeInitialization(Object bean,String beanName)方法对Bean进行处理。入参的bean是当前要处理Bean,beanName是当前Bean的名字,返回对象是处理后的Bean。AOP、动态代理都过BeanPostProcessor实施。
9.调用InitializingBean的afterPropertiesSet()方法。
10.在<bean>中通过init-method属性定义了初始化方法,将执行这个方法。
11.执行BeanPostProcessor的第二个方法,postProcessAfterInitialization(Object bean,String beanName)再次对Bean加工。
12.<bean>种指定Bean的作用范围是scope="prototype",将Bean返回给调用者,使用者管理Bean的后续生命周期;
如果scope="singleton",则把Bean放入SpringIOC容器缓冲池中,把Bean的引用给调用者,Spring管理Bean的后续生命。

大致分为四类
1.Bean的自身方法:调用Bean构造函数实例化Bean、调用Setter设置Bean的属性。
2.Bean级生命周期接口方法:BeanNameAware、BeanFactoryAware、InitializingBean、DisposableBean,这些方法由Bean类直接实现。
3.容器级生命接口方法一般由InstantiationAwareBeanPostProcessor、BeanPostProcessor两个接口实现,实现类附加装置的形式注册到Spring容器中,并通过反射为Spring容器扫描识别。
4.工厂后处理接口的方法:包括AspectJWeavingEnable、CustomAutowireConfigurer、ConfigurationClassPostProcessor等方法。

Resource接口

Spring的装载各种资源,包括配置文件、国际化属性资源等。

方法
boolean exists():资源是否存在
boolean isOpen():资源是否打开
URL getURL()throws IOException:如果底层资源可以表示成URL,则返回对应的URL。
File getFile()throws IOEception:如果底层资源对应一个文件,则返回此文件Flie对象。
InputStream getInputStream()throws IOException:返回对应的输入流。
实现类
WritableResource:可写资源接口
ByteArrayResource:二进制数组表示资源,二进制数组资源可在内存中通过程序构造。
ClassPathResource:类路径下资源,资源以相对类路径方式表示。
FlieSystemResource:文件系统资源,资源文件以系统路径的方式表示。
InputStreamResource:以输入流返回表示的资源。
ServletContextResource为web容器上下文中的资源设计的类,负责以相对web应用根路径加载资源。
UrlResource:URL封装了java.net.URL,它使用户能够访问任何通过URL表示的资源。
PathResource:Spring4.0提供的读取资源文件的新类。Path封装了java.net.URL、java.nio.file.Path、文件系统资源。
它能使用户访问任何可以通过URL、Path、系统文件路径表示的资源。

Resource接口使用代码

public class Test3 {
	public static void main(String []args) {
		//类路径文件
		String classpath="com/jun/IoC/bean/demo.xml";
		//系统路径文件
		String filepath="E:/spring/spring-annotation/src/main/java/com/jun/IoC/bean/demo2.xml";
		//使用系统路径加载文件
		WritableResource res1= new PathResource(filepath);
	        //使用类路径加载文件
		Resource res2 = new ClassPathResource(classpath);
		//给文件设置编码
		EncodedResource encRes = new EncodedResource(res2,"UTF-8");
	}
}

在XML中注入Bean

<?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"
    xmlns:util="http://www.springframework.org/schema/util"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
         http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
         http://www.springframework.org/schema/util 
         http://www.springframework.org/schema/util/spring-util-4.1.xsd">
     
     <!-- Bean的属性注入,实例中需要set方法 -->
     <bean id="user" class="com.jun.IoC.bean.User">
	    <property name="id"><value>11</value></property>
	    <property name="name"><value>小明</value></property>
	    <property name="pass"><value>123456</value></property>
     </bean>
     
     <!-- 构造函数注入 -->
     <bean id="car" class="com.jun.IoC.bean.Car">
         <constructor-arg index="0" value="本田"></constructor-arg>
         <constructor-arg index="1" value="55.5"></constructor-arg>
     </bean>
     <!-- 工厂方法注入 -->
     <bean id="userFactory" class="com.jun.IoC.bean.UserFactory"/>  <!-- 工厂类 -->
     <bean id="user2" factory-bean="userFactory" factory-method="creatUser"/>
     
     <!-- 采用P命名空间 注入信息-->
     <bean id="user2" class="com.jun.IoC.bean.User"
          p:id="2"
          p:name="大黑"
          p:pass="123456" />
      <!-- 方法的注入 -->
      <bean id="user3" class="com.jun.IoC.bean.User">
            <lookup-method name="getCar" bean="car"/>
      </bean>
    
        <!-- 作用域 -->
       <!-- 单例,IOC容器中只有一个Bean -->
       <bean id="user5" class="com.jun.IoC.bean.User" scope="singleton"/>
       <!-- 每次从IOC容器调用时都返回一个新Bean -->
       <bean id="user6" class="com.jun.IoC.bean.User" scope="prototype"/>
       <!-- 每次HTTP请求创建一个新Bean -->
       <bean id="user7" class="com.jun.IoC.bean.User" scope="request"/>
       <!-- 同一个HTTP共享一个Bean -->
       <bean id="user8" class="com.jun.IoC.bean.User" scope="session"/>
       <!-- 同一个全局Session共享一个Bean -->
       <bean id="user9" class="com.jun.IoC.bean.User" scope="globalSession"/>  


 <!-- 扫描包,use-default-filters="true"默认为true会对
        @Component、@Controller、@Service、@Reposity的Bean进行扫描 -->
       <context:component-scan base-package="com" use-default-filters="true">
            <!-- 包含的目标类 目标类是否标注bean进行过滤 -->
           <context:include-filter type="annotation" expression="com.jun.IoC.bean"/>
            <!-- 是否继承或扩展bean进行过滤 -->
           <context:include-filter type="assignable" expression="com.jun.IoC.bean"/>
           <!-- 以Service命名结束的类及它的扩展类和子类进行过滤 -->
           <context:include-filter type="aspectj" expression="com.jun.IoC..*Service+"/>
           <!-- IoC包下的所有类 -->
           <context:include-filter type="regex" expression="com\.jun\.IoC\..*"/>    
          <!--  必须实现XxxTypeFilter -->
           <context:include-filter type="custom" expression="com.jun.IoC.XxxTypeFilter"/>
       </context:component-scan>          
</beans>

初始化BeanFactory

Spring 中,BeanFactory是 IoC 容器的核心接口IoC的规范。
它的职责包括:创建管理对象实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。
BeanFactory 提供的高级配置机制,使得管理任何性质的对象成为可能。

public class Test {
	public static void main(String[]args) {	
		//使用BeanFactory
		//1.定义好Spring配置文件。
		//2.通过Resource对象将Spring配置文件进行抽象成一个Resource对象。
		Resource resource = new ClassPathResource("com/jun/IoC/bean/demo.xml");
		//3.定义好Bean工厂(各种BeanFactory)。
		//BeanFactory bf = new XmlBeanFactory(resource);被废弃
		DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
		//4.定义好XmlBeanDefinitionReader对象,并将工厂作为参数传递进去供后续回调使用。
		XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
		//5.通过XmlBeanDefinitionReader对象读取之前抽象出的Resource(包含XML文件的解析过程)。
		int numb = reader.loadBeanDefinitions(resource);
		//6.IoC容器创建完毕,用户可通过容器获取所需的对象信息。
		User us = (User) factory.getBean("user");
	        System.out.println("BeanFactory"+us.getName());
	}
}

初始化ApplicationContext

ApplicationContext主要实现类是ClassPathXmlApplicationContext(默认从类路径加载配置文件)和
FileSystemXmlApplicationContext(默认从文件系统中加载配置文件)

public class Test2 {
	public static void main(String[]args) {
	    ApplicationContext apc1 = new ClassPathXmlApplicationContext("com/jun/IoC/bean/demo.xml");
	    ApplicationContext apc2 = new FileSystemXmlApplicationContext("E:/spring/spring-annotation/src/main/java/com/jun/IoC/bean/demo2.xml");
	    //加载多个XML
	    ApplicationContext apc3 = new ClassPathXmlApplicationContext(new String[] {"com/jun/IoC/bean/demo.xml","com/jun/IoC/bean/demo2.xml"});
	    User apcUser1 = (User) apc1.getBean("user");
	    System.out.println("apcUser1:"+apcUser1.getName());
	    User apcUser2 = (User) apc2.getBean("user2");
	    System.out.println("apcUser2:"+apcUser2.getName());
	    User apcUser3 = (User) apc3.getBean("user");
	    System.out.println("apcUser3:"+apcUser3.getName());
	}
}

BeanFactory的流程代码

import org.springframework.beans.BeansException;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;

//1.Bean级生命周期,及接口。
public class User implements BeanFactoryAware,BeanNameAware,InitializingBean,DisposableBean{
	private int id;
	private String name;
	private String pass;
	
	private BeanFactory beanFactory;
	private String beanName;
	public User() {
		System.out.println("调用 User 的构造方法");
	}
	@Override
	public String toString() {
		return "User [id=" + id + ", name=" + name + ", pass=" + pass + ", beanName="
				+ beanName + "]";
	}
	public int getId() {
		System.out.println("调用 User 的 getId 方法获取ID");
		return id;
	}
	public void setId(int id) {
		System.out.println("调用 User 的 setId 方法设置ID属性");
		this.id = id;
	}
	public String getName() {
		System.out.println("调用 User 的 getName 方法获取Name");
		return name;
	}
	public void setName(String name) {
		System.out.println("调用 User 的 setName 方法设置Name属性");
		this.name = name;
	}
	public String getPass() {
		System.out.println("调用 User 的 getPass 方法获取Pass");
		return pass;
	}
	public void setPass(String pass) {
		System.out.println("调用 User 的 setPass 方法设置Pass属性");
		this.pass = pass;
	}
	@Override
    //2.BeanFactoryAware 接口方法。
	public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
		System.out.println("BeanFactoryAware接口的setBeanFactory()");
		this.beanFactory=beanFactory;
	}
	@Override
	//3.BeanNameAware 接口方法。
	public void setBeanName(String beanName) {
		System.out.println("BeanNameAware接口的setBeanNamey()");
		this.beanName = beanName;
	}
	@Override
	//4.InitializingBean 接口方法。
	public void afterPropertiesSet() throws Exception {
		System.out.println("InitializingBean接口的afterPropertiesSet()");
	}
	@Override
    //5.DisposableBean 接口方法。
	public void destroy() throws Exception {
		System.out.println("DisposableBean接口的destory()");
	}
	//6.通过<bean>的 init-Method 属性指定初始化方法。
	public void myInit() {
		System.out.println("调用 init-method 指定的 myInit()");
	}
	//7.通过<bean>的 destory-method 属性指定的销毁方法。
	public void myDestory() {
		System.out.println("调用 destory-method指定的myDestory()方法");
	}
}


import java.beans.PropertyDescriptor;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
//容器级生命周期接口,后处理器。
public class MyInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter{
	@Override
	//在实例化Bean之前
	public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {		
		System.out.println();
		System.out.println("后处理器: InstantiationAwareBeanPostProcessorAdapter接口的: postProcessBeforeInstantiation方法");
		System.out.println();
		return null;
	}
	@Override
	//在实例化Bean之后
	public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {	
		System.out.println();	
		System.out.println("后处理器: InstantiationAwareBeanPostProcessorAdapter接口的: postProcessAfterInitialization方法");
		System.out.println();
		return true;
	}
	@Override
	//在设值属性时调用
	public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean,
			String beanName) throws BeansException {
		System.out.println();	
		System.out.println("后处理器: InstantiationAwareBeanPostProcessorAdapter接口的: postProcessPropertyValues方法");
		System.out.println();
		return pvs;
	}
}


import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
//容器级生命周期接口,后处理器。
public class MyBeanPostProcessor implements BeanPostProcessor{
	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		if("Jun".equals(beanName)) {
			User user =(User)bean;
			System.out.println();
			System.out.println("后处理器: BeanPostProcessor接口的postProcessBeforeInitialization方法"
						+ "pass为空 设置为999999");
			System.out.println();	
				user.setPass("999999");
		}
		return bean;
	}
	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		if("Jun".equals(beanName)) {
			User user =(User)bean;
			System.out.println();	
			System.out.println("后处理器: BeanPostProcessor接口的postProcessBeforeInitialization方法"
						+ "ID为0设置为100000");
			System.out.println();	
				user.setId(100000);
		}
		return bean;
	}
}


import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

public class Test {
	public static void main(String[]args) {
	// 配置并启动容器
	Resource resource = new ClassPathResource("com/jun/IoC/beanFactory/user.xml");	
	BeanFactory beanFactory = new DefaultListableBeanFactory();
	
	XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader((DefaultListableBeanFactory)beanFactory);
	reader.loadBeanDefinitions(resource);
	
	//向容器注册 MyBeanPostProcessor 后处理器
	 ((ConfigurableBeanFactory)beanFactory).addBeanPostProcessor(new MyBeanPostProcessor());
	
	//向容器注册 MyInstantiationAwareBeanPostProcessor 后处理器
	 ((ConfigurableBeanFactory)beanFactory).addBeanPostProcessor(new MyInstantiationAwareBeanPostProcessor());
	
	//从容器中获取 User,触发容器实例化Bean,引起Bean生命周期方法的调用。
	 User user = (User)beanFactory.getBean("Jun");
	 System.out.println(user.toString());
	/* user.setPass("654321");
	 System.out.println(user.toString()); */
	 ((DefaultListableBeanFactory)beanFactory).destroySingletons();
	}
}

Bean的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"
    xmlns:util="http://www.springframework.org/schema/util"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
         http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
         http://www.springframework.org/schema/util 
         http://www.springframework.org/schema/util/spring-util-4.1.xsd">
    
      <bean id="Jun" class="com.jun.IoC.beanFactory.User" 
       init-method = "myInit"
       destroy-method = "myDestory"
       p:id ="1"
       p:name = "Jun"
       p:pass = "123456"
       />
</beans>

结果

后处理器: InstantiationAwareBeanPostProcessorAdapter接口的: postProcessBeforeInstantiation方法

调用 User 的构造方法

后处理器: InstantiationAwareBeanPostProcessorAdapter接口的: postProcessAfterInitialization方法


后处理器: InstantiationAwareBeanPostProcessorAdapter接口的: postProcessPropertyValues方法

调用 User 的 setId 方法设置ID属性
调用 User 的 setName 方法设置Name属性
调用 User 的 setPass 方法设置Pass属性
BeanNameAware接口的setBeanNamey()
BeanFactoryAware接口的setBeanFactory()

后处理器: BeanPostProcessor接口的postProcessBeforeInitialization方法pass为空 设置为999999

调用 User 的 setPass 方法设置Pass属性
InitializingBean接口的afterPropertiesSet()
调用 init-method 指定的 myInit()

后处理器: BeanPostProcessor接口的postProcessBeforeInitialization方法ID为0设置为100000

调用 User 的 setId 方法设置ID属性
User [id=100000, name=Jun, pass=999999, beanName=Jun]
DisposableBean接口的destory()
调用 destory-method指定的myDestory()方法

ApplicationContext工作流程

Application继承了HierarchicalBeanFactory和ListableBeanFactory接口(HierarchicalBeanFactory、ListableBeanFactory是BeanFactory的实现接口)

1.ResourceLoader从储存介质加载配置信息,使用Resource表示这个文件。
2.BeanDefinitionReader读取Resource所指向的配置文件,解析配置文件,把文件中的<bean>解析成BeanDefinition对象,保存到BeanDefinitionRegistry。
3.容器扫描BeanDefinitionRegistry中的BeanDefinition对象,通过Java的反射机制自动识别出Bean工厂后处理器(实现BeanFactoryPostProcessor接口的Bean)调用这些Bean工厂后处理器对BeanDefinitionRegistry中的BeanDefinition进行加工处理。
     (1)对占位符的<Bean>元素标签进行解析,得到最终的配置值。对些半成品式的BeanDefinition对象进行加工处理得到成品的BeanDefinition对象。
     (2)对BeanDefinitionRegistry中的BeanDefinition进行扫描,通过Java反射机制找出所有属性编辑器的Bean(实现java.beans.PropertyEditor接口的Bean)
        自动将它们注册到Spring容器的属性编辑注册表中(PropertyEditorRegistry)
4.Spring容器从BeanDefinitionRegistry中取出加工后的BeanDefinition,调用InstantiationStrategy进行实例化。
5.实例化Bean时,Spring容器使用BeanWrapper对Bean进行封装。BeanWrapper提供很多以Java反射机制操作Bean的方法。结合Bean的BeanDefinition级容器中属性编辑器,完成Bean属性的注入。
6.利用容器中注册Bean后处理器(实现BeanPost接口的Bean)对已完成属性设置工作的Bean进行后续加工,装配出Bean。

Spring组件按所承担的角色分为两类

物料组件:Resource、BeanDefinition、PropertyEditor、最终的Bean。
设备组件:ResourceLoader、BeanDefinitionReader、BeanFactoryPostProcessor、InstantiationStrategy、BeanWrapper

BeanDefinition

Spring通过BeanDefinition将配置文件中的<bean>的配置信息转换为容器内部表示。并将这些BeanDefinition注册到BeanDefinitionRegistry中。BeanDefinitionRegistry好比Spring的配置信息内存数据库。
主要经过两个步骤
1.利用BeanDefinitionReader读取配置信息的Resource,通过XML解析器解析配置信息的DOM对象。简单的为每个<bean>生成BeanDefinition半成品对象。
2.利用容器中注册的BeanFactoryPostProcessor对半成品的BeanDefinition进行加工。将占位符的配置解析为实际值,半成品成为成品的BeanDefinition。

InstantiationStrategy

负责根据BeanDefinition对象创建Bean实例。
InstantiationStrategy->SimpleInstantiationStrategy->CglibSubclassingInstantiationStrategy
SimpleInstantiationStrategy是最常见的实例化策略,利用Bean实现类默认构造函数、带参构造函数、工厂方法等创建Bean。
CglibSubclassingInstantiationStrategy扩展了SimpleInstantiationStrategy,为需要进行的方法注入的Bean提供支持。用CGLib类库为Bean动态生成子类。
在子类生成方法注入逻辑,用这个动态生成的子类创建Bean实例。

BeanWrapper
BeanWrapper好比一个代理器,Spring委托BeanW完成Bean的属性填充工作。
Bean实例创建出来通过BeanWrapper的setWrappedInstance(Object obj)方法包装起来,
获取Bean实例和属性编辑器,从BeanDefinitionRegistry中获取BeanDefinition中获取PropertyValue,用属性编辑器对PropertyValue进行转换得到Bean的属性。

Spring的 @Configuration 提供Spring所需的Bean配置信息。

@Configuration
public class AppConf {	
	public void getName() {
		System.out.println("你叫大黑蛋");
	}
	@Bean(name="us")
	public User getUser() {
		return new User();
	}
	@Bean(name="ca")
	public Car getCar() {
		return new Car();
	}
}
public class Test1 {
	public static void main(String[]args) {
		//基于@Configuration类提供的Bean定义信息启动容器
		ApplicationContext cxt = new AnnotationConfigApplicationContext(AppConf.class);
		AppConf apcf=cxt.getBean(AppConf.class);
		apcf.getName();
		test1();
	}
	public static void test1() {
	    AnnotationConfigApplicationContext cxt = new AnnotationConfigApplicationContext();
        /*注册多个configuration配置类*/
	    cxt.register(AppConf.class);
        cxt.refresh();
    	AppConf apcf=cxt.getBean(AppConf.class);
		apcf.getName();
	}
}

一般工作是用XML配置文件直接扫描包,把有注解的类自动加载到IOC中。

<?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:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
         http://www.springframework.org/schema/context
         http://www.springframework.org/schema/context/spring/context/4.1.xsd">
        
        <!-- 扫描包 -->
        <context:component-scan base-package="com.jun"/>
        
</beans>

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值