FactoryBean
普通 bean:在配置文件中定义 bean 类型就是返回类型
工厂 bean:在配置文件定义 bean 类型可以和返回类型不一样
第一步 创建类,让这个类作为工厂 bean,实现接口 FactoryBean
第二步 实现接口里面的方法,在实现的方法中定义返回的 bean 类型
# 编写课程实体类
public class Course {
private String cname; //课程名称
public void setCname(String cname) {
this.cname = cname;
}
@Override
public String toString() {
return "Course{" +
"cname='" + cname + '\'' +
'}';
}
}
# 编写工厂bean
public class MyBean implements FactoryBean<Course> {
//定义返回bean
@Override
public Course getObject() throws Exception {
Course course = new Course();
course.setCname("abc");
return course;
}
@Override
public Class<?> getObjectType() {
return null;
}
@Override
public boolean isSingleton() {
return false;
}
}
# 编写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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="myBean" class="com.ychen.spring.bean.MyBean">
</bean>
</beans>
# 测试方法
@Test
public void test3() {
ApplicationContext context =
new ClassPathXmlApplicationContext("bean3.xml");
Course course = context.getBean("myBean", Course.class);
System.out.println(course);
}
# 控制台
Course{cname='abc'}
Process finished with exit code 0
bean作用域
- 在 Spring 里面,默认情况下,bean 是单实例对象
# book实体类
public class Book {
private List<String> list;
public void setList(List<String> list) {
this.list = list;
}
public void test() {
System.out.println(list);
}
}
# 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:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<!--1 提取list集合类型属性注入-->
<util:list id="bookList">
<value>易筋经</value>
<value>九阴真经</value>
<value>九阳神功</value>
</util:list>
<!--2 提取list集合类型属性注入使用-->
<bean id="book" class="com.ychen.spring.bean.Book" scope="singleton">
<property name="list" ref="bookList"></property>
</bean>
</beans>
# 测试方法
@Test
public void testCollection2() {
ApplicationContext context =
new ClassPathXmlApplicationContext("bean2.xml");
Book book1 = context.getBean("book", Book.class);
Book book2 = context.getBean("book", Book.class);
System.out.println(book1);
System.out.println(book2);
}
# 控制台
com.ychen.spring.bean.Book@2a8448fa
com.ychen.spring.bean.Book@2a8448fa
Process finished with exit code 0
# 测试结果
2个对象的内存地址是一样的,说明是同一个对象,即是单实例
# book实体类
public class Book {
private List<String> list;
public void setList(List<String> list) {
this.list = list;
}
public void test() {
System.out.println(list);
}
}
# 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:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<!--1 提取list集合类型属性注入-->
<util:list id="bookList">
<value>易筋经</value>
<value>九阴真经</value>
<value>九阳神功</value>
</util:list>
<!--2 提取list集合类型属性注入使用-->
<bean id="book" class="com.ychen.spring.bean.Book" scope="singleton">
<property name="list" ref="bookList"></property>
</bean>
</beans>
# 测试方法
@Test
public void testCollection2() {
ApplicationContext context =
new ClassPathXmlApplicationContext("bean2.xml");
Book book1 = context.getBean("book", Book.class);
Book book2 = context.getBean("book", Book.class);
System.out.println(book1);
System.out.println(book2);
}
# 控制台
com.ychen.spring.bean.Book@2a8448fa
com.ychen.spring.bean.Book@6f204a1a
Process finished with exit code 0
# 测试结果
2个对象的内存地址是不一样的,说明不是同一个对象,即是多实例
# 在 spring 配置文件 bean 标签里面有属性(scope)用于设置单实例还是多实例
# scope 属性值如下
第一个值 默认值,singleton,表示是单实例对象
第二个值 prototype,表示是多实例对象
# singleton 和 prototype 区别
第一 singleton 单实例,prototype 多实例
第二 设置 scope 值是 singleton 时候,加载 spring 配置文件时候就会创建单实例对象(ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");)
设置 scope 值是 prototype 时候,不是在加载 spring 配置文件时候创建 对象,在调用 getBean 方法时候创建多实例对象(Book book1 = context.getBean("book", Book.class);)