3.也可以 使用内部bean的方式实现上述效果,对对象类型的属性进行注入: 在案例代码中,UserDaoImpl添加了name属性,因此,不仅仅展示了内部bean,同时也演示了级联赋值的操作:
<!--service和dao对象创建--> <bean id="userService" class="com.ithxh.spring5.service.UserService"> <property name="userDao"> <bean id="userDao" class="com.ithxh.spring5.dao.UserDaoImpl"> <!--对象属性赋值--> <property name="userName" value="黄小黄"></property> </bean> </property> </bean>
2.2.3.2 注入集合
1.注入数组
以Student类的courses数组为例。
<bean id="student" class="com.ithxh.spring5.demo.Student"> <!--数组类型属性注入--> <property name="courses"> <array> <value>java</value> <value>English</value> <value>python</value> </array> </property> </bean>
2.注入List
与上面类似,相关的Student代码省略,不再赘述。set类型的注入也与下面代码类似,将list标签替换成set标签即可。
<bean id="student" class="com.ithxh.spring5.demo.Student"> <!--List类型属性注入--> <property name="list"> <list> <value>java</value> <value>c</value> <value>c++</value> </list> </property> </bean>
3.注入Map
<bean id="student" class="com.ithxh.spring5.demo.Student"> <!--Map类型属性注入--> <property name="map"> <map> <entry key="Java" value="jdk-1.8"></entry> </map> </property> </bean>
以上,如果在集合中存储的Value为对象,则可以通过标签实现,样板代码案例如下:
2.3 工厂Bean
Spring中有两种bean,一种是普通bean(自己创建的),一种是工厂bean(Spring里内置的)。区别如下:
普通bean:在配置文件中定义的bean类型就是返回类型;
工厂bean:在配置文件中定义的bean类型可以和返回类型不一样。
工厂bean实现步骤:
1.创建类,让该类作为工厂bean,实现FactoryBean接口;
2.实现接口里的方法,在实现方法里面返回bean类型
示例如下:
import org.springframework.beans.factory.FactoryBean; import java.util.ArrayList; import java.util.List; /** * @author 兴趣使然黄小黄 * @version 1.0 * 工厂bean示例 */ public class MyBean implements FactoryBean<Student> { @Override public boolean isSingleton() { //返回是否为单例 return FactoryBean.super.isSingleton(); } @Override public Student getObject() throws Exception { //定义返回bean Student student = new Student(); //省略... List<String> strings = new ArrayList<>(); strings.add("黄小黄"); student.setList(strings); //返回... return student; } @Override public Class<?> getObjectType() { return Student.class; } }
2.4 Bean的作用域
在Spring中可以设置创建的bean是单实例还是多实例。默认情况下,创建的bean是单实例对象。
在Spring的bean标签中,存在属性scope可以用于设置,其不同值对应表述如下:
1.默认值,singleton,表示单实例对象;
2.prototype,表示多实例对象;
3.request、session,表示每次创建将其放在域对象中(不常用)。
易错点:简述singleton与prototype的区别
1.singleton表示单实例,prototype表示多实例;
2.设置值为singleton时,在加载spring配置文件的时候就会创建单实例对象;而设置值为prototype时,是在调度getBean()方法的时候,去创建多实例对象。
2.5 Bean的生命周期
1.通过构造创建bean实例(无参构造);
2.为bean的属性设置值和其他bean(调用set方法);
3.调用bean中的初始化方法(需要通过bean标签的init-method属性配置);
4.bean可以使用,对象可以获取;
5.当容器在关闭的时候,调用bean的销毁方法(需要通过bean标签的destroy-method属性配置)。
示例代码:
创建类并设置相应的初始化和销毁方法
public class Student { private String name; public Student(){ System.out.println("调用了无参构造"); } public void setName(String name) { this.name = name; System.out.println("调用了set方法"); } public void initMethod(){ System.out.println("初始化方法"); } public void destroyMethod(){ System.out.println("销毁方法"); } }
文件配置
<bean id="student" class="com.ithxh.spring5.demo.Student" init-method="initMethod" destroy-method="destroyMethod"> <property name="name" value="黄小黄"/> </bean>
测试
@Test public void test1(){ ApplicationContext context = new ClassPathXmlApplicationContext("demo3.xml"); Student student = context.getBean("student", Student.class); System.out.println(student); //手动销毁bean实例 ((ClassPathXmlApplicationContext) context).close(); }
如果创建的类实现了接口BeanPostProcessor,则 创建了后置处理器。在bean生命周期初始化前和初始化后会分别调用postProcessBeforeInitialization 和 postProcessAfterInitialization方法, 配置文件也需要进行相应的配置。
2.6 xml自动装配(偷懒的技巧)
根据指定的装配规则(属性名称或者属性类型),Spring自动将匹配的属性值进行注入。
实现自动装配是通过bean标签的属性autowire配置自动装配,其有两个常用值:
byName根据属性名称自动装配,注入值bean的id和类属性名称一样
byType根据属性类型注入。
演示自动装配
<bean id="student" class="com.ithxh.spring5.demo.Student" autowire="byName"></bean> <bean id="与待装配的属性名一致" class="xxx"></bean>