内容来自《精通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>