常规方式
通过构造方法实例化
1
2
3
4
5
6
7
8
9
10<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="test" class="com.learn.Test" />
<bean id="test1" class="com.learn.Test">
<constructor-arg name="id" value="1"/>
</bean>
</beans>1
2
3
4
5
6
7
8import org.springframework.context.support.ClassPathXmlApplicationContext;
public class DemoApplication {
public static void main(String[] args) {
ClassPathXmlApplicationContext ca=new ClassPathXmlApplicationContext("beans.xml");
Test testA=(Test)ca.getBean("test");
}
}通过静态工厂实例化
1
2
3
4
5
6
7
8
9
10
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="rFactory" class="com.test.TestFactory" factory-method="testFactory"/>
<bean id="rFactory1" class="com.test.TestFactory" factory-method="testFactory">
<constructor-arg name="id" value="111"/>
</bean>
</beans>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19//TestFactory工厂类
public class TestFactory {
//静态方法
public static Test testFactory(){
return new Test();
}
public static Test testFactory(String id){
return new Test(id);
}
}
//DemoApplication.java
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class DemoApplication {
public static void main(String[] args) {
ClassPathXmlApplicationContext ca=new ClassPathXmlApplicationContext("beans.xml");
}
}通过实例工厂实例化
1
2
3
4
5
6
7
8
9
10
11
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="rFactory" class="com.learn.TestFactory" />
<bean id="test" factory-bean="rFactory" factory-method="testFactory"></bean>
<bean id="test1" factory-bean="rFactory" factory-method="testFactory">
<constructor-arg name="id" value="666"></constructor-arg>
</bean>
</beans>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19//TestFactory.java
public class TestFactory {
//不能用静态方法
public Test testFactory(){
return new Test();
}
public Test testFactory(String id){
return new Test(id);
}
}
//DemoApplication.java
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class DemoApplication {
public static void main(String[] args) {
ClassPathXmlApplicationContext ca=new ClassPathXmlApplicationContext("beans.xml");
//Test testA=(Test)ca.getBean("rFactory1");
}
}通过FactoryBean实例化
1
2
3
4
5
6
7
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="test-by-factoryBean" class="com.learn.TestFactoryBean"/>
</beans>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19import org.springframework.beans.factory.FactoryBean;
public class TestFactoryBean implements FactoryBean {
public Object getObject() throws Exception {
return Test.createTest();
}
public Class<?> getObjectType() {
return Test.class;
}
}
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class DemoApplication {
public static void main(String[] args) {
ClassPathXmlApplicationContext ca=new ClassPathXmlApplicationContext("beans.xml");
Test testA=(Test)ca.getBean("test-by-factoryBean");
}
}
特殊方式
ServiceLoader 利用JDK里面的反向控制
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19public final class ServiceLoader<S>
implements Iterable<S>
{
private static final String PREFIX = "META-INF/services/";
//....
}
需要在classpath下创建META-INF/services/目录,在此目录下创建一个文件名为工厂接口的文件(注意不需要后缀),此文件里面放上此接口的全类路径
└── resources
├── META-INF
│ └── services
│ └── com.learn.TestFactory
├── application.properties
└── beans.xml
注意:com.learn.TestFactory 是个文件
里面的内容为工厂接口:
com.learn.DefaultTestFactory
调用DemoApplication.java1
2
3
4
5
6
7
8
9
10
11
12
13
14import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.Iterator;
import java.util.ServiceLoader;
public class DemoApplication {
public static void main(String[] args) {
ClassPathXmlApplicationContext ca=new ClassPathXmlApplicationContext("beans.xml");
ServiceLoader<TestFactory> serviceLoader= ServiceLoader.load(TestFactory.class,Thread.currentThread().getContextClassLoader());
Iterator<TestFactory> iterator = serviceLoader.iterator();
while(iterator.hasNext()){
TestFactory next = iterator.next();
System.out.println(next.testFactory());
}
}
}ServiceLoaderFactoryBean
1
2
3
4
5
6
7
8
9
10
11beans.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="instance-by-serviceLoaderFactoryBean" class="org.springframework.beans.factory.serviceloader.ServiceLoaderFactoryBean">
<property name="serviceType" value="com.learn.TestFactory"></property>
</bean>
</beans>1
2
3
4
5
6
7
8
9
10
11
12//调用DemoApplication.java
public class DemoApplication {
public static void main(String[] args) {
ClassPathXmlApplicationContext ca=new ClassPathXmlApplicationContext("beans.xml");
ServiceLoader bean = ca.getBean("instance-by-serviceLoaderFactoryBean", ServiceLoader.class);
Iterator iterator = bean.iterator();
while (iterator.hasNext()){
TestFactory next = (TestFactory) iterator.next();
System.out.println(next.testFactory());
}
}
}AutowireCapableBeanFactory#createBean
1
2
3
4
5
6
7
8
9package com.learn;
public class DemoApplication {
public static void main(String[] args) {
ApplicationContext ac=new ClassPathXmlApplicationContext("beans.xml");
AutowireCapableBeanFactory abf = ac.getAutowireCapableBeanFactory();
DefaultTestFactory bean = abf.createBean(DefaultTestFactory.class);
System.out.println(bean.testFactory());
}
}BeanDefinitionRegistry#registerBeanDefinition
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15public class DemoApplication {
public static void main(String[] args) {
AnnotationConfigApplicationContext ac=new AnnotationConfigApplicationContext();
ac.register(DemoApplication.class);
registerBean(ac,"testa");
ac.refresh();
Test testa = (Test) ac.getBean("testa");
System.out.println(testa);
ac.close();
}
public static void registerBean(BeanDefinitionRegistry reg,String beanName){
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(Test.class);
reg.registerBeanDefinition(beanName,beanDefinitionBuilder.getBeanDefinition());
}
}
来源:
https://rumenz.com/rumenbiji/Spring-Bean-common-instantiate.html
https://rumenz..com/rumenbiji/Spring-Bean-special-instantiate.html