BeanDefinition注冊(cè)
- XML配置元信息
<bean name="...." .../> - Java注解配置元信息: 1.@Bean 2.@Component3.@Import
/**
* 3.通過@Import方式進(jìn)行導(dǎo)入
*/
@Import(AnnotationBeanDefinitionDemo.Config.class)
public class AnnotationBeanDefinitionDemo {
public static void main(String[] args) {
//創(chuàng)建BeanFactory容器
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
//注冊(cè)Configuration Class(配置類)
applicationContext.register(AnnotationBeanDefinitionDemo.class);
//啟動(dòng)spring應(yīng)用上下文
applicationContext.refresh();
//按照類型依賴查找
System.out.println("config 的所有 Beans"+applicationContext.getBeansOfType(Config.class));
System.out.println("user 的所有 Beans"+applicationContext.getBeansOfType(User.class));
//顯示的關(guān)閉spring應(yīng)用上下文
applicationContext.close();
}
/**
* 2.通過@component方式 定義當(dāng)前類作為Spring Bean(組件)
*/
@Component
public static class Config{
/**
* 1.通過Java 注解的方式凉逛,定義了一個(gè)bean
* @return
*/
@Bean(name={"user","zhangsan-user"})
public User user(){
User user = new User();
user.setId(1L);
user.setName("zhangsan");
return user;
}
}
}
-
Java API 配置元信息
- 命名方式:BeanDefinitionRegistry#registerBeanDefinition(String,BeanDefiniton)
- 非命名方式:
- BeanDefinitionReaderUtils#registerWithGeneratedName(AbstractBeanDefinition,BeanDefinitonRegistry)
/**
* 命名Bean注冊(cè)方式
* @param registry
* @param beanName
*/
public static void registerUserBeanDefinition(BeanDefinitionRegistry registry,String beanName){
BeanDefinitionBuilder beanDefinitionBuilder = genericBeanDefinition(User.class);
beanDefinitionBuilder.addPropertyValue("id",1)
.addPropertyValue("name","zhangsan");
//判斷如果BeanName參數(shù)存在時(shí)
if(StringUtils.hasText(beanName)){
//注冊(cè)BeanDefinition
registry.registerBeanDefinition(beanName,beanDefinitionBuilder.getBeanDefinition());
}else {
//非命名的注冊(cè)方法
BeanDefinitionReaderUtils.registerWithGeneratedName(beanDefinitionBuilder.getBeanDefinition(),registry);
}
}
/**
* 非命名注冊(cè)bean
* @param registry
*/
public static void registerUserBeanDefinition(BeanDefinitionRegistry registry){
registerUserBeanDefinition(registry,null);
}
* 配置類方式:AnnotatedBeanDefinitionReader#register(Class....)
Spring Bean的實(shí)例化
Bean實(shí)例化(Instantiation)
- 常規(guī)方式
- 通過構(gòu)造器(配置元信息:XML腌歉、Java注解和Java API)
- 通過靜態(tài)工廠方法(配置元信息:XML和Java API)
- 通過Bean工廠方法(配置元信息:XML和Java API)
- 通過FactoryBean(配置元信息:XML、Java注解和Java API)
例如:通過xml方式進(jìn)行相關(guān)的配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 靜態(tài)方法實(shí)例化bean-->
<bean id="user-by-static-method" class="com.test.ioc.overview.dependency.domian.User"
factory-method="createUser"/>
<!--實(shí)例(Bean)的方法實(shí)例化Bean-->
<bean class="com.test.thinking.in.spring.bean.factory.DefaultUserFactroy"/>
<!--通過FactoryBean的方式實(shí)例化bean-->
<bean id="user-by-factroy-bean" class="com.test.thinking.in.spring.bean.factory.UserFactoryBean"/>
</beans>
- 特殊方式
- 通過ServiceLoaderFactoryBean(配置元信息:XML、Java注解和Java API)
public final class ServiceLoader<S>
implements Iterable<S>
{
private static final String PREFIX = "META-INF/services/";</pre>
ServiceLoader默認(rèn)的文件路徑是"META-INF/services/"下面迁筛,我們先新建一個(gè)相關(guān)目錄,然后寫入對(duì)應(yīng)的類路徑

配置對(duì)應(yīng)的XML文件:
``` xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="userFactoryServiceLoader" class="org.springframework.beans.factory.serviceloader.ServiceLoaderFactoryBean">
<property name="serviceType" value="com.test.thinking.in.spring.bean.factory.UserFactory"/>
</bean>
</beans>
通過ServiceLoader對(duì)應(yīng)的API獲取:
public static void main(String[] args) {
BeanFactory beanFactory = new ClassPathXmlApplicationContext("META-INF/special-bean-instination-context.xml");
ServiceLoader<UserFactory> serviceLoader = beanFactory.getBean("userFactoryServiceLoader", ServiceLoader.class);
displayServiceLoader( serviceLoader);
demoServiceLoader();
}
public static void demoServiceLoader(){
ServiceLoader<UserFactory> serviceLoader = ServiceLoader.load(UserFactory.class, Thread.currentThread().getContextClassLoader());
displayServiceLoader(serviceLoader);
}
private static void displayServiceLoader(ServiceLoader<UserFactory> serviceLoader){
Iterator<UserFactory> iterator = serviceLoader.iterator();
while (iterator.hasNext()){
UserFactory userFactory = iterator.next();
System.out.println(userFactory.createUser());
}
}
* 通過AutowireCapableBeanFactory#createBean(java.lang.Class,int,boolen)
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("META-INF/special-bean-instination-context.xml");
//通過ApplicationContext獲取AutowireCapableBeanFactory
AutowireCapableBeanFactory beanFactory = applicationContext.getAutowireCapableBeanFactory();
ServiceLoader<UserFactory> serviceLoader = beanFactory.getBean("userFactoryServiceLoader", ServiceLoader.class);
displayServiceLoader( serviceLoader);
// demoServiceLoader();
//創(chuàng)建beanfactory對(duì)象,通過AutowireCapableBeanFactory
UserFactory userFactory = beanFactory.createBean(DefaultUserFactroy.class);
userFactory.createUser();
* 通過BeanDefinitionRegistry#registerBeanDefinition(String,BeanDefiniton)