Spring有两种类型bean,一种是普通bean,另一种是工厂bean(FactoryBean)
- 普通bean:在配置文件中定义的bean类型就是返回类型
- FactoryBean:在配置文件中定义的bean类型可以和返回类型不同
创建FactoryBean的方法: - 创建一个类(myBean),让这个类实现FactoryBean接口,实现其中的方法
- 在实现的方法中,定义返回bean的类型
public class myBean implements FactoryBean<Object> {
//这个返回的是BookList类型,
//@Override
//public BookList getObject() throws Exception {
// List<String> strings = new ArrayList<>();
// strings.add("java");
// BookList bookList = new BookList();
// bookList.setBookName(strings);
// return bookList;
//}
//这个返回的是ArrAndCollection类型
@Override
public ArrAndCollection getObject() throws Exception {
Map<String, String> map = new HashMap<>();
map.put("key1", "我是arrAndCollection的Map集合中的值");
Set<String> set = new HashSet<>();
set.add("我是ArrAndCollection类中的Set集合中的值");
ArrAndCollection arrAndCollection = new ArrAndCollection();
String [] strArr = {"我是ArrAndCollection类中的ArrString数组"};
arrAndCollection.setArrString(strArr);
arrAndCollection.setMap(map);
arrAndCollection.setSet(set);
return arrAndCollection;
}
@Override
public Class<?> getObjectType() {
return null;
}
@Override
public boolean isSingleton() {
return FactoryBean.super.isSingleton();
}
}
在xml文件中配置
<!--配置FactoryBean的bean-->
<bean id="myBean" class="com.hyp.spring5.factoryBean.myBean"></bean>
测试:
这个测试程序测试的是返回值类型为BookList的
//BookList类
public class BookList {
private List bookName;
public void setBookName(List bookName) {
this.bookName = bookName;
}
public void showBook(){
System.out.println(bookName);
}
@Override
public String toString() {
return "BookList{" +
"bookName=" + bookName +
'}';
}
}
//测试:
@Test
public void testBean(){
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean3.xml");
//在这里传入要返回什么类型的类的Class对象
BookList myBean = context.getBean("myBean", BookList.class);
myBean.showBook();
}
运行结果
这个测试程序的返回值是ArrAndCollection
//ArrAndCollection类
public class ArrAndCollection {
//数组
private String[] arrString;
private Map<String,String> map;
private Set set;
private List list;
BookList bookList;
public void setList(List list) {
this.list = list;
}
public void setBookList(BookList bookList) {
this.bookList = bookList;
}
public void setArrString(String[] arrString) {
this.arrString = arrString;
}
public void setMap(Map<String, String> map) {
this.map = map;
}
public void setSet(Set set) {
this.set = set;
}
public void sout(){
System.out.println("arr "+Arrays.toString(arrString)+" map "+map
+" set "+set+"list"+list);
}
}
//测试:
@Test
public void testBean2(){
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean3.xml");
ArrAndCollection myBean = context.getBean("myBean", ArrAndCollection.class);
myBean.sout();
}
运行结果:
为什么FactoryBean可以指定返回类型,因为:
Spring在调用getBean()方法时在底层调用的是 getObject()方法
而我们的myBean实现了FactoryBean接口并且实现了其中的getObjet()方法
其中getObject的返回类型就是最终方法的返回类型
注入集合属性
注入List Map Set集合类型和数组类型属性
首先 先创建一个类,这个类中有Set Map List 和数组类型的属性
创建这个类:
public class ArrAndCollection {
//数组
private String[] arrString;
//Map集合
private Map<String,String> map;
//set集合
private Set set;
//list集合
private List list;
BookList bookList;
public void setList(List list) {
this.list = list;
}
public void setBookList(BookList bookList) {
this.bookList = bookList;
}
public void setArrString(String[] arrString) {
this.arrString = arrString;
}
public void setMap(Map<String, String> map) {
this.map = map;
}
public void setSet(Set set) {
this.set = set;
}
public void sout(){
System.out.println("arr "+Arrays.toString(arrString)+" map "+map
+" set "+set+"list"+list);
}
}
然后在xml文件中进行注入
<!--注入类中的数组和集合属性-->
<bean id="arrAndCollection" class="com.hyp.spring5.ArrAndCollection">
<property name="arrString">
<array>
<value>数组元素1</value>
<value>数组元素2</value>
<value>数组元素3</value>
<value>数组元素4</value>
</array>
</property>
<property name="map">
<map>
<entry key="k1" value="v1"></entry>
<entry key="k2" value="v2"></entry>
<entry key="k3" value="v3"></entry>
</map>
</property>
<property name="set">
<set>
<value>set元素1</value>
<value>set元素2</value>
<value>set元素3</value>
<value>set元素4</value>
</set>
</property>
<property name="list">
<list>
<ref bean="book1"></ref>
<ref bean="book2"></ref>
</list>
</property>
</bean>
测试:
@Test
public void testArrAndColl(){
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
ArrAndCollection collection = context.getBean("arrAndCollection", ArrAndCollection.class);
collection.sout();
}
运行结果:
另一种方式,将xml文件中的Map Set List等属性注入
创建两个类用来测试
- BookList类
package com.hyp.spring5;
import java.util.List;
public class BookList {
private List bookName;
public void setBookName(List bookName) {
this.bookName = bookName;
}
public void showBook(){
System.out.println(bookName);
}
@Override
public String toString() {
return "BookList{" +
"bookName=" + bookName +
'}';
}
}
在xml文件中进行配置
<!--提取list集合属性注入-->
<util:list id="bookNameList">
<value>java技术</value>
<value>mysql技术</value>
<value>Spring框架</value>
</util:list>
<bean id="bookList" class="com.hyp.spring5.BookList">
<property name="bookName" ref="bookNameList"></property>
</bean>
测试类:
@Test
public void testBookList(){
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");
BookList bookList = context.getBean("bookList", BookList.class);
bookList.showBook();
}
结果:
- BookMap类
/**
* @author Han
* @data 2023/6/3
* @apiNode
*/
public class BookMap {
private Map<String,String> bookName;
public void setBookName(Map bookName) {
this.bookName = bookName;
}
public void showBook(){
System.out.println(bookName);
}
@Override
public String toString() {
return "BookMap{" +
"bookName=" + bookName +
'}';
}
}
在xml文件中进行配置
<!--设置map集合-->
<util:map id="bookNameMap">
<entry key="one" value="java1"></entry>
<entry key="two" value="java2"></entry>
<entry key="three" value="java3"></entry>
</util:map>
<bean id="bookMap" class="com.hyp.spring5.BookMap">
<property name="bookName" ref="bookNameMap"></property>
</bean>
测试类:
@Test
public void testBookMap(){
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");
BookMap bookMap = context.getBean("bookMap", BookMap.class);
bookMap.showBook();
}
结果: