Spring(4)装配Bean

来源:互联网 发布:淘宝 手办时光机 编辑:程序博客网 时间:2024/05/22 04:52

在Spring容器内拼凑bean叫作装配。装配bean的时候,需要告诉容器,哪些bean以及容器如何使用依赖注入将它们配合在一起

1 scope配置

<bean scope="prototype|singleton|request|session"></bean>
singleton:单例 (默认值)
prototype:原型(每次都会创建新的,会对性能产生影响)
request:一次请求有效(Javaweb开发中)
session:session级有效(javaweb开发中)
global-session:在web中spring容器ApplicationContext一致

ApplicationContext acc = new ClassPathXmlApplicationContext("applicationContext.xml");IDCardService idc = (IDCardService) acc.getBean("iDCardService");IDCardService idc1 = (IDCardService) acc.getBean("iDCardService");System.out.println(idc + " " + idc1);

2 init-method和destroy-method配置

<bean id="changeLetter" init-method="init" destroy-method="mydestroy" class="com.test.service.imp.UpperLetter"></bean>

也可以使用注解的方式:@PostConstruct和@PreDestroy

// import javax.annotation.*;@PostConstructpublic void init() {    System.out.println("自己配置的init 方法调用 ");}@PreDestroypublic void mydestroy() {    System.out.println("自己配置的mydestroy 方法调用 ");}

3 通过setter方法注入依赖

<bean>元素的<property>子元素指明了使用它们的set方法来注入。可以注入任何东西,从基本数据类型到集合类,甚至是应用系统的bean(可以引用也可以为内部bean)。

①集合类型(set、list、map)配置

对象被装配到set中使用<set>元素,被装配到list或数组中使用<List>元素,此外还有map对应<map>元素

<!-- String --><property name="name">    <value>jiaozl</value></property><!-- Bean--><property name="userId" ref="idCardService"></property><!-- 内部Bean--><property name="userId">    <bean id="idCardService" class="com.service.IDCardService">        <property name="IDS" value="99885566"></property>    </bean></property>

Bean类

public class Department {    private String name;    private String[] empName;    private List<Employee> empList;    private Set<Employee> empSet;    private Map<String, Employee> empMap;}public class Employee {    private String name;    private int id;}

xml配置

<bean id="department" class="com.test.collection.Department">    <property name="name" value="财务部"></property>    <!-- 给数组注入值 -->    <property name="empName">        <list>            <value>小明111</value>            <value>小明222</value>            <value>小明333</value>        </list>    </property>    <property name="empList">        <list>            <ref bean="emp1"/>            <ref bean="emp2"/>        </list>    </property>    <property name="empSet">        <set>            <ref bean="emp1"/>            <ref bean="emp2"/>        </set>    </property>    <property name="empMap">        <map>            <entry key="1" value-ref="emp1"></entry>            <entry key="2" value-ref="emp2"></entry>        </map>    </property></bean><!-- ----------------------------------------------- --><bean id="emp1" class="com.test.collection.Employee">    <property name="name" value="北京"></property>    <property name="id" value="1"></property></bean><bean id="emp2" class="com.test.collection.Employee">    <property name="name" value="南京"></property>    <property name="id" value="2"></property></bean>

2 继承配置parent

Bean类

public class Student {    protected String name;    protected int age;}public class Graduate extends Student {    private String degree;}

xml文件

<bean id="student" class="com.test.inherit.Student">    <property name="name" value="jiaozl"/>    <property name="age" value="13"/></bean><bean id="graduate" parent="student" class="com.test.inherit.Graduate">    <!-- 如果单独配置属性name,则会替换继承的数据 -->    <property name="name" value="xiaoming"/>    <property name="degree" value="学士"/></bean>

3 装配Properties(Java中的一种对象)

private Properties pro;
<!-- 给属性集合配置 --><property name="pro">    <props>        <prop key="pp1">abcd</prop>        <prop key="pp2">hello</prop>    </props></property>

4 赋空值null

若bean的属性是集合类型,按如下处理:
设置null:

<property name="barList">    <null/></property>

4 通过构造函数注入值

生成bean默认调用无参构造函数。

public class Employee {    private String name;    private int age;    public Employee(String name, int age) {        super();        this.name = name;        this.age = age;    }}
<!-- 通过构造函数注入属性值 --><bean id="employee1" class="com.test.constructor.Employee">    <constructor-arg index="0" type="java.lang.String" value="xiaoming"/>    <constructor-arg index="1" type="int" value="23"/></bean>

set注入的缺点是无法清晰表达哪些属性是必须的,哪些是可选的;
构造注入的优势在于通过构造强制依赖关系,不可能实例化不完全的或无法使用的bean。

5 自动装配(autowire)

  • Spring IoC容器可以自动装配(autowire)相互协作bean之间的关联关系。因此,如果可能的话,可以自动让Spring通过检查BeanFactory中的内容,来替我们指定bean的写作者(其他被依赖的bean)。
  • autowire一共有五种类型。由于autowire可以针对单个bean进行设置,因此可以让有些bean使用autowire,有些bean不采用。
  • 在xml配置文件中,可以在<bean/>元素中使用autowire属性指定。
  • 默认模式为不自动装配;
  • 对于自动装配,如果手动装配,则自动选项失效

① byName根据属性名自动装配

此选项将检查容器,并根据名字查找与属性完全一直的bean,并将其与属性自动装配。

② byType根据属性类型自动装配

此选项将检查容器,寻找和属性类型相同的bean,找不到,装不上;如果找到多个,就会抛出异常。

③ constructor

此选项将检查容器,按照参数的类型装配,查找和bean(master)的构造参数一致的一个或多个bean,若找不到或找到多个,抛异常。

④ autodetect

在②和③之间选择一个方式;不确定性的处理与②和③一致。

⑤ default

这个需要在<beans default-autowire="byType" />指定
这样指定后,所有未指定的bean,均采用这种方式;
这里的默认值是no;
而对于单个bean来说,默认值是default。

public class Dog {    private String name;    private int age;}public class Master {    private String name;    private Dog dog;    public Master() {    }    public Master(Dog dog) {        this.dog = dog;    }}
<bean id="master" class="com.test.autowire.Master" autowire="byName|byType|constructor|autodetect">    <property name="name" value="jiaozl"></property></bean><bean id="dog" class="com.test.autowire.Dog">    <property name="name" value="xiaohuang"></property>    <property name="age" value="3"></property></bean>

6 annotation注解方式

Spring2.5提供了<context:annotation-config />配置。
改配置可以激活在类中探测到的各种注解
@Required @Autowire @PostConstrct @PreDestroy @Resource @EJB @PersistenceContext @WebServiceRef等
也可选择为这些注解激活单独的后处理器。
如:AutowiredAnnotationBeanPostProcessor(处理自动装配)
注意:该标记不能激活事务处理,需要使用tx:annotation-driven

7 Spring特殊bean

让spring特殊对待这些bean,使他们可以:
- 通过配置后加工bean,涉及到Bean和Bean工厂生命周期。
- 改变依赖注入,将字符串转换成其他类型。
- 从属性文件装载信息,包括信息国际化。
- 监听并处理其他bean及spring发布的系统消息。
- 知道自己在spring中的唯一标识。

① 实现了BeanPostProcessor接口的后置处理器

在bean装载后,对bean做一些后处理工作
(http://blog.csdn.net/u013943420/article/details/71326702#t5)

② 感知bean之实现BeanFactoryAware 接口

载入所有bean的定义,实例化bean之前,对BeanFactory做一些后处理工作
(http://blog.csdn.net/u013943420/article/details/71326702#t3)
如果使用的是应用上下文,不需要将它注册为Bean工厂后处理器。上下文会自动注册它。按照正常的Bean声明即可。
其他感知bean实现接口:(http://blog.csdn.net/u013943420/article/details/71326702#t2)
(http://blog.csdn.net/u013943420/article/details/71326702#t4)

分散配置(有两种方式引入文件)

将配置文件分成几个分散的配置文件。如数据源。
① 需要额外的bean(不常用

<bean class="xxx.xxx.PropertyPlaceholderConfigurer">    <property name="locations">        <list>            <value>com/test/dispatch/db.properties</value>            <value>com/test/dispatch/db2.properties</value>        </list>    </property></bean>

②通过名字空间配置
xml配置文件

<!-- 引入db.properties文件--> <context:property-placeholder location="classpath:com/test/dispatch/db.properties, com/test/dispatch/db2.properties"/><!-- 配置DBUtil对象     ${}占位符 --><bean id="dbutil" class="com.test.dispatch.DBUtil"><property name="drivername" value="${drivername}"></property><property name="url" value="${url}"></property><property name="name" value="${name}"></property><property name="pwd" value = "${pwd}" /></bean><bean id="dbutil2" class="com.test.dispatch.DBUtil"><property name="drivername" value="${db2.drivername}"></property><property name="url" value="${db2.url}"></property><property name="name" value="${db2.name}"></property><property name="pwd" value = "${db2.pwd}" /></bean></beans>

db.properties文件

drivername=oracle\:jdbc\:driver\:OracleDriverurl=jdbc\:oracle\:thin\:@localhost\:1521\:orclname=scottpwd=tiger
0 0