一、依赖注入的示例:基于XML的配置方式
1、定义Message接口及实现类
public interface MessageService {
StringgetMessage();
}
public class MessageServiceImplimplements MessageService {
private String username;
private int age;
public MessageServiceImpl(String username, int age) {
this.username = username;
this.age = age;
}
public StringgetMessage() {return "Hello World! " +username +",age is " +age;}
}
2、定义打印器MessagePrinter
public class MessagePrinter {
final private MessageServiceservice;
public MessagePrinter(MessageService service) {this.service = service;}
public void printMessage() {
System.out.println(this.service.getMessage());//打印消息
}
}
3、定义应用主类
public class Application {
public static void main(String[] args) {
@SuppressWarnings("resource")
ApplicationContext context =new ClassPathXmlApplicationContext("spring.xml");
MessagePrinter printer = context.getBean(MessagePrinter.class);
printer.printMessage();
}
}
4、定义配置文件spring.xml,放resources目录下
<?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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 定义bean -->
<bean id="messageServiceImpl" class="com.spring.di.service.MessageServiceImpl">
<constructor-arg name="username" value="xiao ming" />
<constructor-arg name="age" value="10" />
</bean>
<bean id="messagePrinter" class="com.spring.di.MessagePrinter">
<constructor-arg name="service" ref="messageServiceImpl" />
</bean>
</beans>
![](https://img.haomeiwen.com/i17879487/f6351d7764480f19.png)
二、依赖注入的配置
Spring基于XML的配置元数据,通过支持<property/>、<constructor-arg/>等元素来实现。
1、直接赋值
直接赋值支持字符串和原始类型的数据。元素<property/>中的value属性允许以友好易读的形式来配置属性或构造参数,spring将这些字符串的值转换为指定的类型。
![](https://img.haomeiwen.com/i17879487/cfceea2bd4524e6c.png)
另外也可以定义一个java.util.Properties类型的实例,spring容器会将<value>中的文本通过JavaBean的PropertyEditor机制转换为一个java.util.Properties实例,如下:
![](https://img.haomeiwen.com/i17879487/e6b6653657062d6a.png)
2、引用其他bean
如果bean之间有协作关系,可以引用其他的bean。ref属性是元素<constructor-arg>和<property>中的一个终极标签,可以通过它来配置一个bean引用其他bean。当需要引用一个bean时,被引用的bean会先实例化,然后配置属性,即引用的依赖。若该bean是单例则该bean会由容器初始化。所有引用最终都是对另一个对象的引用,bean的范围及校验取决于开发者释放通过bean、local、parent这些属性来指定对象的id或name属性。
通过指定bean属性中的<ref/>来指定依赖是一种常见的方式,可以引用容器或如父容器中的bean,无论是否在同一个XML中定义都可以。bean属性的值可以与其他引用bean中的id属性一致或其中的一个name属性一致。
<ref bean="userBean"/>
通过指定bean的parent属性会创建一个引用到当前容器的父容器,parent属性的值可以与目标bean的id属性一致,或与目标bean的name属性中的一个一致,且目标bean必须是当前引用目标bean容器的父容器。一般只有在存在层次化容器关系,且希望通过代码来包裹父容器中一个存在的bean时才会用到此属性。
引用bean示例:
父容器中的bean:messageService
<bean id="messageService" class="com.spring.di.service.MessageServiceImpl"/>
子容器中也存在相同名称的bean:messageService
<bean id="messageService" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target">
<ref parent="messageService"/>
</property>
</bean>
由于父子容器中都有相同id的bean,为避免歧义需要加parent属性。
3、内部bean
内部bean:定义在<bean>元素中<constructor-arg>或<property>内部的bean。
内部bean的id或名称不需要指定,若指定了,容器也不会用其作为区分bean的标识符,反而会无视内部bean的scope标签。内部bean总是匿名的且随外部bean来创建的,我们无法将内部bean注入外部bean以外的其他bean。
<bean id="out" class="...">
<property name="target">
<bean class="com.xx.User">
<property name="name" value="tom">
<property name="age" value="10">
</bean>
</property>
</bean>
4、集合
在<list>、<set>、<map>、<props>元素中,可以配置Java集合类型List、Set、Map、Properties的属性和参数。
![](https://img.haomeiwen.com/i17879487/e6fd7d9070940eec.png)
5、null及空字符的值
spring会将属性的空参数当成空字符串来处理,如下所示:
<bean id="complexObject" class="com.test.ComplexObject">
<property name="email" value="" />
</bean>
等同于complexObject.setEmail("");
<null/>元素用来处理null值:
<bean id="complexObject" class="com.test.ComplexObject">
<property name="email">
<null/>
</property>
</bean>
等同于complexObject.setEmail(null);
6、XML短域名空间
p命名空间:可以使用bean的属性,而不使用嵌套的<property>元素就可以实现需要注入的依赖。
![](https://img.haomeiwen.com/i17879487/5674ff2e3d323244.png)
c命名空间:允许内联的属性来配置构造参数,而不使用<constructor-arg>元素。
![](https://img.haomeiwen.com/i17879487/0bb3312ded5b2b13.png)
7、复合属性
我们还可以在配置属性时配置复合属性的名称,只要保证除最后一个属性外,其余的属性值不为null即可,如下:
![](https://img.haomeiwen.com/i17879487/3760e047479b7b62.png)
![](https://img.haomeiwen.com/i17879487/6adfee9dbfa74da1.png)
三、使用depends-on
如果一个bean是另外一个bean的依赖,则这个bean通常是另一个bean的一个属性。一般可以在配置XML元数据时使用<ref/>标签,有时bean之间的依赖关系并不是直接关联的,比如需要调用类的静态实例化工具来触发(如数据库驱动注册)。depends-on属性会让明确的、强依赖的bean在引用之前初始化。如下所示:
<bean id="bean1" class="xx.xx.Bean" depends-on="manager"/>
<bean id="manager" class="xx.xx.ManagerBean"/>
若要依赖多个bean,可提供多个名称作为depends-on的值,以逗号、空格或分号分隔。如下:
<bean id="bean1" class="xx.xx.Bean" depends-on="manager1,manager2">
<property name="manager" ref="manager1" />
</bean>
<bean id="manager1" class="xx.xx.ManagerBean"/>
<bean id="manager2" class="xx.xx.ManagerBean"/>
--参考文献《Srping5开发大全》
网友评论