环境介绍
创建maven工程并导入Spring对应依赖,在resources目录下创建spring配置文件applicationContext.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">
</beans>
1.构造器方式
在com.xxx包下创建名为testBean的类,并添加无参构造方法,为验证效果,在无参构造器中添加输出语句
package com.xxx;
public class testBean {
public testBean() {
//在无参构造器被使用时进行输出
System.out.println(this + " 无参构造方法被执行");
}
}
xml文件配置bean的id与全限定名
<bean id="testBean" class="com.xxx.bean.testBean"/>
同时可以使用name属性为bean设置别名
配置完成后进行测试,使用ApplicationContext加载XML
//使用ApplicationContext加载XML
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//通过id获取bean
Object testBean = context.getBean("testBean");
在加载XML出打上断点并运行调试,可以发现无参构造方法在加载配置时被执行,并且在BeanFactory下的Map集合---singletonObjects 中可以找到该bean。
这说明使用这种方式管理bean,默认情况下会在XML被加载时就把配置中的bean进行实例化且存入BeanFactory的容器中。
2.静态工厂方式
创建类TestBeanFactory,并定义获取实例的静态方法
package com.xxx;
public class TestBeanFactory {
public static TestBean testBean() {
//在方法执行时输出语句并返回实例
System.out.println("工厂方法执行");
return new TestBean();
}
}
接下来在xml中配置bean,将全限定名定义为工厂类,并配置工厂方法,而对于TestBean这个类无需进行配置
<!--定义id为testBean的bean,全限定名配置为工厂类,并设定工厂方法-->
<bean id="testBean" class="com.xxx.TestBeanFactory" factory-method="testBean"/>
以同样的方式运行测试,同样是在xml加载时输出了“工厂方法被执行”,通过观察beanFactory中的内容可以发现singletonObjects中key为“testBean”的值并不是TestBeanFactory这个工厂类的实例,而是存放了并没有配置的TestBean类的实例。
这说明使用静态工厂方式,会直接通过静态方法获取bean,并将从中获取到的实例与配置的id或name相关联,而非与工厂类相关联。
3.实例工厂方式
创建类TestFactoryBean,并定义获取实例的非静态方法
package com.xxx;
public class TestFactoryBean {
public TestBean testBean() {
System.out.println("工厂方法被执行");
return new TestBean();
}
}
继续在xml中配置bean,此次除了需要配置TestFactoryBean外,还要再配置一个从实例工厂中获取的bean。
<!--定义id为TestFactoryBean的bean,全限定名配置为实例工厂类-->
<bean id="testFactoryBean" class="com.xxx.TestFactoryBean"/>
<!--配置id为testBean的bean,并配置获取该bean的工厂类与方法-->
<bean id="testBean" factory-bean="testFactoryBean" factory-method="testBean"/>
运行测试后,通过观察beanFactory中的内容可以发现,虽然没有直接为testBean指定全限定名,但singletonObjects中同时存在testFactoryBean与testBean,且工厂方法的语句被执行。
这可以说明,testBean的获取是通过被实例化了的testFactoryBean中指定的方法获取到的。
参数配置
如果需要使用到参数,则需要在bean标签下嵌套<contructor-arg>标签,并配置name与value或ref属性(取决于参数类型)。
且无论使用以上任一种方式配置bean时遇到需要参数的情况,均可以使用以下方式进行参数配置。
<!--定义id为testBean的bean,全限定名为TestBean类-->
<bean id="testBean" class="com.xxx.TestBean">
<!--配置构造器参数,参数名分别为desc与num,对应值分别为description与100-->
<constructor-arg name="desc" value="description"/>
<constructor-arg name="num" value="100"/>
</bean>
在此处仅展示有参构造方式。为方便测试,我将构造器方法的输出语句进行了调整。
package com.xxx;
public class TestBean {
public TestBean(String desc, int num) {
//当有参构造方法被执行时输出语句
System.out.println(this + " 有参构造方法被执行---desc=" + desc + ",num=" + num);
}
}
运行并查看结果,发现成功执行了有参构造并拿到了我们配置的参数。
*工厂方式配置的参数为工厂方法的参数,而非构造方法的参数。