Spring依赖注入---<2>
2016-11-05 10:22
477 查看
学习Spring,时间一长就把最开始学的基础生疏掉了...算是写个笔记以便以后复习吧
什么bean,在Spring里可以理解为组件。可以联系一下我在前一篇笔记《理解Spring框架的控制反转——学习笔记》中放进IoC容器里的东西,比如说放在容器实例化的类,在容器中依赖注入的类...等等。可以先配置一个简单的bean看看,代码如下:
首先是一个创建一个Bean类,其实也就是个普通的类,为其中属性提供了setter而已:
复制代码
public class Fruit{
private String color;
private String name;
public Fruit(){}
public Fruit(String name,String color){
this.color=color;
this.name=name;
}
public void setColor(String color) {
this.color = color;
}
public void setName(String name) {
this.name = name;
}
public void mySaid(){
System.out.println("我是"+name+",我的颜色是:"+color);
}
}
复制代码
配置文件就索性名为bean.xml,放在classpath下,以便待会实例化容器的时候找到它,代码如下:
复制代码
<?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-2.5.xsd"> <bean id="fruit" class="com.czh.Fruit">
<!--下面是setter注入-->
<property name="color" value="red"/>
<property name="name">
<value>apple</value>
</property>
<!--下面是构造器注入-->
<constructor-arg>
<value>red</value>
</constructor-arg>
<constructor-arg>
<value>red</value>
</constructor-arg>
</bean>
</beans>
复制代码
这样一来,bean就配置好了。上面代码里setter注入用了两种写法,效果是相同的,都会将value值注入到相应的属性中。
而且要注意的是,<property>标签是指要注入的属性,它是通过name的值来找到相应属性的。正如上面代码所示,<property name="color" value="red"/>,那么它就会去找这个bean所设置的类里(上面代码里,类为”com.czh.Fruit")的一个名为setColor的方法,然后注入value值。同理,如果property的name为“abc",则容器也会到类里找setAbc方法。
组件写好了,也配置进了容器中,下一步就是实例化容器:
复制代码
public class Main{
public static void main(String[] args) {
ApplicationContext context=new ClassPathXmlApplicationContext("bean.xml");//实例化容器
Fruit fruit=context.getBean("fruit");//找到配置好的bean
fruit.mySaid();
}
}
复制代码
容器实例化的方法还有很多种,用ClassPathXmlApplicationContext类可以从classpath路径上实例化容器。实例化容器之后,就可以用getBean方法去找配置在容器中的组件了,比如context.getBean("fruit");这个时候容器就把该注入的内容注入进组件,并实例化该组件,于是这时候调用该组件的mySaid()方法,可以看到输出"我是apple,我的颜色是:red".
上面介绍了最简单的配置,和实例化容器。现在来看看如何在Bean配置文件指定对Bean的引用..这句话可以理解成这样:A类中需要引用B类的方法,首先需要在A类中实例化B类,然后使用B类方法。但是在使用容器的情况下,可以通过Setter或者构造器把B类注入到A类中...这就是一个Bean对另一个Bean的引用了,具体看下面代码:
复制代码
public class Fruit{
private String color;
private String name;
private Price price; //Price类
public Fruit(){}
public Fruit(String name,String color,Price price){
this.color=color;
this.name=name;
this.price=price;
}
public void setColor(String color) {
this.color = color;
}
public void setName(String name) {
this.name = name;
}
public void setPrice(Price price){
this.price=price;
}
public void mySaid(){
System.out.println("我是"+name+",我的颜色是:"+color+",我的价格是:"+price.getPrice());
}
}
复制代码
这里需要用到Price类:
复制代码
public class Price{
private String price;
public void setPrice(String price){
this.price=price;
}
public String getPrice(){
return price;
}
}
复制代码
于此同时,bean的配置应该改为:声明另一个bean(即price),并注入到Fruit中
复制代码
<?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-2.5.xsd"> <bean id="fruit" class="com.czh.Fruit">
<!--下面是setter注入-->
<property name="color" value="red"/>
<property name="name">
<value>apple</value>
</property>
<property name="price">
<ref bean="price"/><!-- 用ref的bean属性可以引用其他XML的bean -->
<ref local="price"/><!-- 用ref的bean属性只能引用本XML的bean -->
</property>
<!--下面是构造器注入-->
<constructor-arg>
<value>red</value>
</constructor-arg>
<constructor-arg>
<value>red</value>
</constructor-arg>
<constructor-arg>
<ref bean="price"/>
</constructor-arg>
</bean>
<bean id="price" class="com.czh.Price">
<property name="price" value="10"/>
</bean>
</beans>
复制代码
从上面的配置中,应该可以很清楚看到,要引用bean只需要在property下用<ref>标签去获得bean的id即可。
当然,也可以这么写:<property name="price" ref="price">
还有另一个引用bean的方式,那就是:内部bean。内部bean的意思就是说直接把<bean id="price" class="com.czh.price">...</bean>写在Fruit Bean的property下。这样说可能不是很明白,那就看看下面的代码吧:(内部bean的缺点是,放在的Fruit Bean里面,则只有Fruit Bean可以引用它,其他的Bean是无法找到它的)
复制代码
<?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-2.5.xsd"> <bean id="fruit" class="com.czh.Fruit">
<!--下面是setter注入-->
...
<property name="price">
<bean id="price" class="com.czh.Price">
<property name="price" value="10"/>
</bean>
</property>
<!--下面是构造器注入-->
...
<constructor-arg>
<bean id="price" class="com.czh.Price">
<property name="price" value="10"/>
</bean>
</constructor-arg>
</bean>
</beans>
复制代码
最基本的注入配置已经了解了。接下来应该考虑的两个问题是:1、假如配置的时候忘记了注入怎么办,漏掉了几个property导致输出都是null却很难从那么多配置中一下找到写少的部分。2、每一个Bean都要自己配置和注入,有没有什么办法可以减少手工配置?
这两个问题的解决就要看“基于注解的配置:@Required和@Autowired"...
首先来看看@Requried,顺便理解一下注解在框架中起的作用
检查属性是否注入是上面所说要考虑的两个问题之一。在spring中可以使用依赖检查的特性来解决这个问题,依赖检查很简单,只需要在bean里添加一个dependency-check属性就可以了,具体的看看下面代码:
复制代码
<?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-2.5.xsd"> <bean id="fruit" class="com.czh.Fruit" dependency-check="all">
<!--下面是setter注入-->
...
<property name="price">
<bean id="price" class="com.czh.Price">
<property name="price" value="10"/>
</bean>
</property>
<!--下面是构造器注入-->
...
<constructor-arg>
<bean id="price" class="com.czh.Price">
<property name="price" value="10"/>
</bean>
</constructor-arg>
</bean>
</beans>
复制代码
dependency-check="all"意味着对简单类型的注入,和对象的注入(即bean的引用)都进行检查。
dependency-check="simple"意味着对简单类型(int,string...)的注入进行检查。
dependency-check="object"意味着对 对象的注入(即bean的引用)进行检查。它们一旦检查未setter,就会抛出UnsatisfiedDenpendencyException。
不过这个dependency-check好像在spring 3.0中使用会报错,所以当基于注解的@Requried可以用于与它一样的作用的时候,就使用@Requried注解吧。
Spring的一个Bean后置处理器(RequiredAnnotationBeanPostProcessor)可以检查所有具有@Requried注解的属性是否被设置,可以继续上面水果类的例子看看这个@Requried如何放置,代码如下:
复制代码
public class Fruit{
private String color;
private String name;
private Price price; //Price类
public Fruit(){}
public Fruit(String name,String color,Price price){
this.color=color;
this.name=name;
this.price=price;
}
@Requried
public void setColor(String color) {
this.color = color;
}
@Requried
public void setName(String name) {
this.name = name;
}
@Requried
public void setPrice(Price price){
this.price=price;
}
public void mySaid(){
System.out.println("我是"+name+",我的颜色是:"+color+",我的价格是:"+price.getPrice());
}
}
复制代码
放置@Required注解很简单,像上面代码那样就可以了。Bean.xml那里还得做点功夫,不过也很简单,Spring 2.5以上的版本,我们只需要在xml中加上一句话就可以了,像这样:<context:annotation-config/>,不过还是看看代码吧,在beans那块加了些东西,否则会无法使用<context>标签。代码如下:
复制代码
<?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-2.5.xsd http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd"> <context:annotation-config/>
...
什么bean,在Spring里可以理解为组件。可以联系一下我在前一篇笔记《理解Spring框架的控制反转——学习笔记》中放进IoC容器里的东西,比如说放在容器实例化的类,在容器中依赖注入的类...等等。可以先配置一个简单的bean看看,代码如下:
首先是一个创建一个Bean类,其实也就是个普通的类,为其中属性提供了setter而已:
复制代码
public class Fruit{
private String color;
private String name;
public Fruit(){}
public Fruit(String name,String color){
this.color=color;
this.name=name;
}
public void setColor(String color) {
this.color = color;
}
public void setName(String name) {
this.name = name;
}
public void mySaid(){
System.out.println("我是"+name+",我的颜色是:"+color);
}
}
复制代码
配置文件就索性名为bean.xml,放在classpath下,以便待会实例化容器的时候找到它,代码如下:
复制代码
<?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-2.5.xsd"> <bean id="fruit" class="com.czh.Fruit">
<!--下面是setter注入-->
<property name="color" value="red"/>
<property name="name">
<value>apple</value>
</property>
<!--下面是构造器注入-->
<constructor-arg>
<value>red</value>
</constructor-arg>
<constructor-arg>
<value>red</value>
</constructor-arg>
</bean>
</beans>
复制代码
这样一来,bean就配置好了。上面代码里setter注入用了两种写法,效果是相同的,都会将value值注入到相应的属性中。
而且要注意的是,<property>标签是指要注入的属性,它是通过name的值来找到相应属性的。正如上面代码所示,<property name="color" value="red"/>,那么它就会去找这个bean所设置的类里(上面代码里,类为”com.czh.Fruit")的一个名为setColor的方法,然后注入value值。同理,如果property的name为“abc",则容器也会到类里找setAbc方法。
组件写好了,也配置进了容器中,下一步就是实例化容器:
复制代码
public class Main{
public static void main(String[] args) {
ApplicationContext context=new ClassPathXmlApplicationContext("bean.xml");//实例化容器
Fruit fruit=context.getBean("fruit");//找到配置好的bean
fruit.mySaid();
}
}
复制代码
容器实例化的方法还有很多种,用ClassPathXmlApplicationContext类可以从classpath路径上实例化容器。实例化容器之后,就可以用getBean方法去找配置在容器中的组件了,比如context.getBean("fruit");这个时候容器就把该注入的内容注入进组件,并实例化该组件,于是这时候调用该组件的mySaid()方法,可以看到输出"我是apple,我的颜色是:red".
上面介绍了最简单的配置,和实例化容器。现在来看看如何在Bean配置文件指定对Bean的引用..这句话可以理解成这样:A类中需要引用B类的方法,首先需要在A类中实例化B类,然后使用B类方法。但是在使用容器的情况下,可以通过Setter或者构造器把B类注入到A类中...这就是一个Bean对另一个Bean的引用了,具体看下面代码:
复制代码
public class Fruit{
private String color;
private String name;
private Price price; //Price类
public Fruit(){}
public Fruit(String name,String color,Price price){
this.color=color;
this.name=name;
this.price=price;
}
public void setColor(String color) {
this.color = color;
}
public void setName(String name) {
this.name = name;
}
public void setPrice(Price price){
this.price=price;
}
public void mySaid(){
System.out.println("我是"+name+",我的颜色是:"+color+",我的价格是:"+price.getPrice());
}
}
复制代码
这里需要用到Price类:
复制代码
public class Price{
private String price;
public void setPrice(String price){
this.price=price;
}
public String getPrice(){
return price;
}
}
复制代码
于此同时,bean的配置应该改为:声明另一个bean(即price),并注入到Fruit中
复制代码
<?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-2.5.xsd"> <bean id="fruit" class="com.czh.Fruit">
<!--下面是setter注入-->
<property name="color" value="red"/>
<property name="name">
<value>apple</value>
</property>
<property name="price">
<ref bean="price"/><!-- 用ref的bean属性可以引用其他XML的bean -->
<ref local="price"/><!-- 用ref的bean属性只能引用本XML的bean -->
</property>
<!--下面是构造器注入-->
<constructor-arg>
<value>red</value>
</constructor-arg>
<constructor-arg>
<value>red</value>
</constructor-arg>
<constructor-arg>
<ref bean="price"/>
</constructor-arg>
</bean>
<bean id="price" class="com.czh.Price">
<property name="price" value="10"/>
</bean>
</beans>
复制代码
从上面的配置中,应该可以很清楚看到,要引用bean只需要在property下用<ref>标签去获得bean的id即可。
当然,也可以这么写:<property name="price" ref="price">
还有另一个引用bean的方式,那就是:内部bean。内部bean的意思就是说直接把<bean id="price" class="com.czh.price">...</bean>写在Fruit Bean的property下。这样说可能不是很明白,那就看看下面的代码吧:(内部bean的缺点是,放在的Fruit Bean里面,则只有Fruit Bean可以引用它,其他的Bean是无法找到它的)
复制代码
<?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-2.5.xsd"> <bean id="fruit" class="com.czh.Fruit">
<!--下面是setter注入-->
...
<property name="price">
<bean id="price" class="com.czh.Price">
<property name="price" value="10"/>
</bean>
</property>
<!--下面是构造器注入-->
...
<constructor-arg>
<bean id="price" class="com.czh.Price">
<property name="price" value="10"/>
</bean>
</constructor-arg>
</bean>
</beans>
复制代码
最基本的注入配置已经了解了。接下来应该考虑的两个问题是:1、假如配置的时候忘记了注入怎么办,漏掉了几个property导致输出都是null却很难从那么多配置中一下找到写少的部分。2、每一个Bean都要自己配置和注入,有没有什么办法可以减少手工配置?
这两个问题的解决就要看“基于注解的配置:@Required和@Autowired"...
首先来看看@Requried,顺便理解一下注解在框架中起的作用
检查属性是否注入是上面所说要考虑的两个问题之一。在spring中可以使用依赖检查的特性来解决这个问题,依赖检查很简单,只需要在bean里添加一个dependency-check属性就可以了,具体的看看下面代码:
复制代码
<?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-2.5.xsd"> <bean id="fruit" class="com.czh.Fruit" dependency-check="all">
<!--下面是setter注入-->
...
<property name="price">
<bean id="price" class="com.czh.Price">
<property name="price" value="10"/>
</bean>
</property>
<!--下面是构造器注入-->
...
<constructor-arg>
<bean id="price" class="com.czh.Price">
<property name="price" value="10"/>
</bean>
</constructor-arg>
</bean>
</beans>
复制代码
dependency-check="all"意味着对简单类型的注入,和对象的注入(即bean的引用)都进行检查。
dependency-check="simple"意味着对简单类型(int,string...)的注入进行检查。
dependency-check="object"意味着对 对象的注入(即bean的引用)进行检查。它们一旦检查未setter,就会抛出UnsatisfiedDenpendencyException。
不过这个dependency-check好像在spring 3.0中使用会报错,所以当基于注解的@Requried可以用于与它一样的作用的时候,就使用@Requried注解吧。
Spring的一个Bean后置处理器(RequiredAnnotationBeanPostProcessor)可以检查所有具有@Requried注解的属性是否被设置,可以继续上面水果类的例子看看这个@Requried如何放置,代码如下:
复制代码
public class Fruit{
private String color;
private String name;
private Price price; //Price类
public Fruit(){}
public Fruit(String name,String color,Price price){
this.color=color;
this.name=name;
this.price=price;
}
@Requried
public void setColor(String color) {
this.color = color;
}
@Requried
public void setName(String name) {
this.name = name;
}
@Requried
public void setPrice(Price price){
this.price=price;
}
public void mySaid(){
System.out.println("我是"+name+",我的颜色是:"+color+",我的价格是:"+price.getPrice());
}
}
复制代码
放置@Required注解很简单,像上面代码那样就可以了。Bean.xml那里还得做点功夫,不过也很简单,Spring 2.5以上的版本,我们只需要在xml中加上一句话就可以了,像这样:<context:annotation-config/>,不过还是看看代码吧,在beans那块加了些东西,否则会无法使用<context>标签。代码如下:
复制代码
<?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-2.5.xsd http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd"> <context:annotation-config/>
...
相关文章推荐
- Spring零配置通过注解实现Bean依赖注入总结<转>
- spring注解或依赖注入模拟MVC结构案例<五>
- spring容器DI依赖注入对象<三>
- spring注解注入:&lt;context:component-scan&gt;详解
- spring 中配置bean的注入是<property>的name与与ref的id名需要一样吗??
- spring注解注入:<context:component-scan>详解
- Spring入门到精通<一> 依赖注入
- spring注解注入:<context:component-scan>详解
- Spring系列【09】使用<prop>标签为Java持久属性集注入值
- spring 自动注入bean,不用一个一个去配置<bean/>的方法
- spring注解注入:<context:component-scan>
- spring注解注入:<context:component-scan>详解
- spring中注解注入<context:component-scan>的使用说明
- 依赖注入那些事儿 <转>
- Spring远程调用技术<2>-Hessian和Burlap
- spring注解注入:<context:component-scan>详解
- Spring中利用AOP对领域对象(非依赖注入的对象,如new操作符、反射的方式生存的对象)下面是spring配置文件的一部分 <context:load-time-weaver /> <be
- Spring类的自动注入<context:component-scan base-package="com.**.dao" />
- spring:使用<prop>标签为Java持久属性集注入值
- 报错:spring属性注入时<constructor-arg>标签不可出现属性“name”,这是什么原因呢?