1、创建一个properties文件,列出需要创建的对象的全限定类型
userService=com.zjhc.beanByHand.UserService
bookService=com.zjhc.beanByHand.BookService
2、创建一个bean工厂类,来通过反射创建对象
public class BeanFactory {
//定义一个静态的配置文件对象
private static Properties props;
//定义一个存放对象的Map容器
private static Map<String,Object> beans;
//通过静态块给props赋值
static{
try {
//实例化props对象
props = new Properties();
//通过类加载器获取加载配置文件的流,并且将文件加到输入流
InputStream in = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
//加载bean配置文件
props.load(in);
//实例化容器
beans = new HashMap<String, Object>();
//取出配置文件种所有的key
Enumeration keys = props.keys();
while(keys.hasMoreElements()){
//取出每个key
String key = keys.nextElement().toString();
//根据key获取value
String beanPath = props.getProperty(key);
//反射创建对象
Object value = Class.forName(beanPath).newInstance();
//将创建好的对象放入容器
beans.put(key,value);
}
} catch (Exception e) {
throw new ExceptionInInitializerError("配置文件初始化创建对象异常....");
}
}
//根据bean的名称获取对象
public static Object getBean(String beanName){
return beans.get(beanName);
}
}
测试:
public class UserService {
public static void main(String[] args) {
BookService bookService = (BookService) BeanFactory.getBean("bookService");
System.out.println(bookService);
}
}
public class BookService {
public static void main(String[] args) {
UserService userService = (UserService) BeanFactory.getBean("userService");
System.out.println(userService);
}
}
结果:
com.zjhc.beanByHand.UserService@7440e464
com.zjhc.beanByHand.BookService@7440e464
调用类的构造方法获取对应的bean实例,是使用最多的方式,这种方式只需要在xml的bean元素中指定class属性,spring容器内部会自动调用该类型的构造方法来创建bean对象,将其放在容器中以供使用
<bean id="bean名称" name="bean名称或者别名" class="bean的完整类型名称">
<constructor-arg index="0" value="bean的值" ref="引用的bean名称" />
<constructor-arg index="1" value="bean的值" ref="引用的bean名称" />
<constructor-arg index="2" value="bean的值" ref="引用的bean名称" />
....
<constructor-arg index="n" value="bean的值" ref="引用的bean名称" />
bean>
@Data
public class UserModel {
private String name;
private int age;
public UserModel(){
this.name = "我是通过反射调用UserModel的无参构造创建的";
}
public UserModel(String name,int age){
this.name = name;
this.age = age;
}
}
<bean id="userModel1" class="com.zjhc.model.UserModel"/>
<bean id="userModel2" class="com.zjhc.model.UserModel">
<constructor-arg index="0" value="我是通过反射调用UserModel有参构造创建的"/>
<constructor-arg index="1" value="11"/>
bean>
@Test
public void test(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
for (String beanName : context.getBeanDefinitionNames()) {
System.out.println(beanName+" : "+context.getBean(beanName));
}
}
我们可以创建静态工厂,内部提供一些静态方法来生成所需要的对象,将这些静态方法创建的对象交给spring以供使用
<bean id="bean名称" name="" class="静态工厂完整类名" factory-method="静态工厂的方法">
<constructor-arg index="0" value="bean的值" ref="引用的bean名称" />
<constructor-arg index="1" value="bean的值" ref="引用的bean名称" />
<constructor-arg index="2" value="bean的值" ref="引用的bean名称" />
....
<constructor-arg index="n" value="bean的值" ref="引用的bean名称" />
</bean>
public class UserModelStaticFactory {
/**
* 静态无参方法创建Usermodel
* @return
*/
public static UserModel builder1(){
System.out.println(UserModel.class+".builder1()");
UserModel userModel = new UserModel();
userModel.setName("我是通过静态的UserModel无参方法创建的");
return userModel;
}
/**
* 静态有参方法创建Usermodel
* @return
*/
public static UserModel builder2(String name,int age){
System.out.println(UserModel.class+".builder2()");
UserModel userModel = new UserModel();
userModel.setName(name);
userModel.setAge(age);
return userModel;
}
}
<bean id="ceateBeanByStaticFactory1" class="com.zjhc.model.UserModelStaticFactory" factory-method="builder1"/>
<bean id="createBeanByStaticFactory2" class="com.zjhc.model.UserModelStaticFactory" factory-method="builder2">
<constructor-arg index="0" value="我是通过静态的UserModel有参方法创建的"/>
<constructor-arg index="1" value="27"/>
bean>
@Test
public void test(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
System.out.println("spring容器中所有bean如下:");
for (String beanName : context.getBeanDefinitionNames()) {
System.out.println(beanName+" : "+context.getBean(beanName));
}
}
让spring容器去调用某些对象的某些实例方法来生成bean对象放在容器中以供使用
<bean id="bean名称" factory-bean="需要调用的实例对象bean名称" factory-method="bean对象中的方法">
<constructor-arg index="0" value="bean的值" ref="引用的bean名称" />
<constructor-arg index="1" value="bean的值" ref="引用的bean名称" />
<constructor-arg index="2" value="bean的值" ref="引用的bean名称" />
....
<constructor-arg index="n" value="bean的值" ref="引用的bean名称" />
bean>
public class CreateBeanByBeanInstanceFactory {
public UserModel builder1(){
UserModel userModel = new UserModel();
userModel.setName("我是通过实例工厂的无参方法创建的");
return userModel;
}
public UserModel builder2(String name,int age){
UserModel userModel = new UserModel();
userModel.setName(name);
userModel.setAge(age);
return userModel;
}
}
<bean id="beanInstanceFactory" class="com.zjhc.model.CreateBeanByBeanInstanceFactory"/>
<bean id="createBeanByBeabInstance1" factory-bean="beanInstanceFactory" factory-method="builder1"/>
<bean id="createBeanByBeabInstance2" factory-bean="beanInstanceFactory" factory-method="builder2">
<constructor-arg index="0" value="我是通过实例工厂的有参方法创建的"/>
<constructor-arg index="1" value="28"/>
bean>
@Test
public void test(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
System.out.println("spring容器中所有bean如下:");
for (String beanName : context.getBeanDefinitionNames()) {
System.out.println(beanName+" : "+context.getBean(beanName));
}
}
FactoryBean接口可以让spring容器通过这个接口的实现来创建我们需要的bean对象
public interface FactoryBean<T> {
/**
* 返回创建好的对象
*/
@Nullable
T getObject() throws Exception;
/**
* 返回需要创建的对象的类型
*/
@Nullable
Class<?> getObjectType();
/**
* bean是否是单例的
**/
default boolean isSingleton() {
return true;
}
}
接口中有3个方法,前面2个方法需要我们去实现,getObject方法内部由开发者自己去实现对象的创建,然后将创建好的对象返回给Spring容器,getObjectType需要指定我们创建的bean的类型;最后一个方法isSingleton表示通过这个接口创建的对象是否是单例的,如果返回false,那么每次从容器中获取对象的时候都会调用这个接口的getObject() 去生成bean对象。
public class CreateBeanByFactoryBean implements FactoryBean<UserModel> {
private int count = 1;
@Nullable
@Override
public UserModel getObject() throws Exception { //1
UserModel userModel = new UserModel();
userModel.setName("我是通过FactoryBean创建的第"+count+++ "对象"); //4
userModel.setAge(29);
return userModel;
}
@Nullable
@Override
public Class<?> getObjectType() {
return UserModel.class; //2
}
@Override
public boolean isSingleton() { //3
return true;
}
}
step1:返回了一个创建好的UserModel对象
step2:返回对象的Class对象
step3:返回true,表示创建的对象是单例的,那么我们每次从容器中获取这个对象的时候都是同一个对象
step4:此处用到了一个count,通过这个一会可以看出isSingleton不同返回值的时候从容器获取的bean是否是同一个
3. beans.xml
<bean id="createBeanByFactoryBean" class="com.zjhc.model.CreateBeanByFactoryBean"/>
@Test
public void test(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
System.out.println("spring容器中所有bean如下:");
for (String beanName : context.getBeanDefinitionNames()) {
System.out.println(beanName+" : "+context.getBean(beanName));
}
System.out.println("=======================================================");
System.out.println("createBeanByFactoryBean:"+context.getBean("createBeanByFactoryBean"));
System.out.println("createBeanByFactoryBean:"+context.getBean("createBeanByFactoryBean"));
}
@Override
public boolean isSingleton() { //3
return false;
}