课程咨询 :186 8716 1620      qq:2066486918

昆明Java培训 > 达内新闻 > Spring设置注入和构造注入的区别
  • Spring设置注入和构造注入的区别

    发布:昆明Java培训      来源:达内新闻      时间:2016-10-21

  • 昆明Java培训班的老师这一期给大家讲Spring设置注入和构造注入的区别

    设置注入是先通过调用无参构造器创建一个bean实例,然后调用对应的setter方法注入依赖关系;而构造注入则直接调用有参数的构造器,当bean实例创建完成后,已经完成了依赖关系的注入。另外这两种依赖注入的方式,并没有绝对的好坏,只是适应的场景有所不同。

    setter方法注入:

    Entity

    public class Happy {

    private String happyInfo;

    public void happy(){

    System.out.println(happyInfo);

    }

    public String getHappyInfo() {

    return happyInfo;

    }

    public void setHappyInfo(String happyInfo) {

    this.happyInfo = happyInfo;

    }

    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">

    <!-- IOC将Happy交给Spring管理-->

    <bean id="happy" class="cn.wgy.day_01.entity.Happy">

    <!-- DI从setInfo方法得知,Happy依赖info属性,注入           赋值-->

    <!--通过框架来赋值,不能用set()方法来赋值 -->

    <!--happyinfo是set()提供的 -->

    <property name="happyInfo" value="中秋快乐"></property>      

    <!-- <property ame="happyInfo">

    <value>中秋快乐</value>

    </property> -->

    </bean>

    </beans> 

    test类

    public static void main(String[] args) {

    //获取上下文对象

    //ApplicationContext context2=new FileSystemXmlApplicationContext("applicationContext.xml");

    //BeanFactory beanf=new FileSystemXmlApplicationContext("applicationContext.xml");

    ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");

    //   Object getBean(String name) throws BeansException;

    Happy happy = (Happy) context.getBean("happy");

    happy.happy();

    }

    }

    昆明Java培训班的老师提醒注意:ApplicationContext ,其实还有BeauFactory也可以,那么它们两的区别是啥呢?

    BeanFacotry是spring中比较原始的Factory。如XMLBeanFactory就是一种典型的BeanFactory。原始的BeanFactory无法支持spring的许多插件,如AOP功能、Web应用等。

    ApplicationContext接口,它由BeanFactory接口派生而来,因而提供BeanFactory所有的功能。ApplicationContext以一种更向面向框架的方式工作以及对上下文进行分层和实现继承,ApplicationContext包还提供了以下的功能:

    01.MessageSource,提供国际化的消息访问 

    02.资源访问,如URL和文件 

    03.事件传播 

    04.载入多个(有继承关系)上下文,使得每一个上下文都专注于一个特定的层次,比如应用的web层 

    1.利用MessageSource进行国际化 

    BeanFactory是不支持国际化功能的,因为BeanFactory没有扩展Spring中MessageResource接口。相反,由于ApplicationContext扩展了MessageResource接口,因而具有消息处理的能力(i18N)

    2.强大的事件机制(Event) 

    基本上牵涉到事件(Event)方面的设计,就离不开观察者模式。不明白观察者模式的朋友,最好上网了解下。因为,这种模式在java开发中是比较常用的,又是比较重要的。

    ApplicationContext的事件机制主要通过ApplicationEvent和ApplicationListener这两个接口来提供的,和java swing中的事件机制一样。即当ApplicationContext中发布一个事件的时,所有扩展了ApplicationListener的Bean都将会接受到这个事件,并进行相应的处理。

    Spring提供了部分内置事件,主要有以下几种: 

    ContextRefreshedEvent:ApplicationContext发送该事件时,表示该容器中所有的Bean都已经被装载完成,此ApplicationContext已就绪可用

    ContextStartedEvent:生命周期beans的启动信号 

    ContextStoppedEvent:生命周期beans的停止信号 

    ContextClosedEvent:ApplicationContext关闭事件,则context不能刷新和重启,从而所有的singleton bean全部销毁(因为singleton bean是存在容器缓存中的)

    虽然,spring提供了许多内置事件,但用户也可根据自己需要来扩展spriong中的事物。注意,要扩展的事件都要实现ApplicationEvent接口。 

    3.底层资源的访问 

    ApplicationContext扩展了ResourceLoader(资源加载器)接口,从而可以用来加载多个Resource,而BeanFactory是没有扩展ResourceLoader

    4.对Web应用的支持 

    与BeanFactory通常以编程的方式被创建不同的是,ApplicationContext能以声明的方式创建,如使用ContextLoader。当然你也可以使用ApplicationContext的实现之一来以编程的方式创建ApplicationContext实例。

    ContextLoader有两个实现:ContextLoaderListener和ContextLoaderServlet。它们两个有着同样的功能,除了listener不能在Servlet 2.2兼容的容器中使用。自从Servelt 2.4规范,listener被要求在web应用启动后初始化。很多2.3兼容的容器已经实现了这个特性。使用哪一个取决于你自己,但是如果所有的条件都一样,你大概会更喜欢ContextLoaderListener;关于兼容方面的更多信息可以参照ContextLoaderServlet的JavaDoc。

    这个listener需要检查contextConfigLocation参数。如果不存在的话,它将默认使用/WEB-INF/applicationContext.xml。如果它存在,它就会用预先定义的分隔符(逗号,分号和空格)分开分割字符串,并将这些值作为应用上下文将要搜索的位置。ContextLoaderServlet可以用来替换ContextLoaderListener。这个servlet像listener那样使用contextConfigLocation参数。

    5.其它区别 

    1).BeanFactroy采用的是延迟加载形式来注入Bean的,即只有在使用到某个Bean时(调用getBean()),才对该Bean进行加载实例化,这样,我们就不能发现一些存在的spring的配置问题。而ApplicationContext则相反,它是在容器启动时,一次性创建了所有的Bean。这样,在容器启动时,我们就可以发现Spring中存在的配置错误。

    2).BeanFactory和ApplicationContext都支持BeanPostProcessor、BeanFactoryPostProcessor的使用,但两者之间的区别是:BeanFactory需要手动注册,而ApplicationContext则是自动注册

    构造器注入:

    其他的代码都差不多,这里我就直接写applicationContext.xml

    ">

    <!--构造器的注入 -->

    <bean id="user1" class="cn.wgy.day01.entity.User">

    <constructor-arg index="0" type="java.lang.String" value="Promise"/>

    <constructor-arg index="1" type="java.lang.String" value="Promise@163.com"/>

    </bean>

    </beans>

    多种方式实现依赖注入

    设值注入: 普通属性,域属性(JavaBean属性)

    构造注入:普通属性,域属性(JavaBean属性)

    命名空间p注入:普通属性,域属性(JavaBean属性)

    我们使用前要先要在Spring配置文件中引入p命名空间:xmlns:p="http://www.springframework.org/schema/p"

    <bean id="user" class="cn.wgy.day01.entity.User" p:username="Promise">

    <!--通过value标签注入直接量 -->

    <property ame="id">

    <value type="java.lang.Integer">20</value>

    </property>

    </bean>

    <!--案例二:注入引用bean -->

    <bean id="dao" class="cn.wgy.day01.dao.impl.UserDao"/>

    <bean id="biz" class="cn.wgy.day01.biz.impl.UserBiz" >

    <property name="dao">

    <ref bean="dao"/>

    </property>

    </bean>

    注入不同数据类型:

    1.注入直接量

    2.引用bean组件

    3.使用内部bean

    4.注入集合类型的属性

    5.注入null和空字符串

    <!--p命名空间注入属性值-->

    <!--案例一:普通的属性-->

    <bean id="user" class="cn.wgy.day01.entity.User" p:username="Promise"></bean>

    <!--案例二:引用Bean的属性-->

    <bean id="dao" class="cn.wgy.day01.dao.impl.UserDao" />

    <!--p命名空间注入的方式-->

    <bean id="biz" class="cn.wgy.day01.biz.impl.UserBiz" p:dao-ref="dao"></bean>

    <!--案例三:注入集合类型的属性-->

    <!--01.List集合-->

    <bean id="list" class="cn.wgy.day01.entity.CollectionBean">

    <property name="names">

    <list>

    <value>Promise</value>

    <value>Promise2</value>

    </list>

    </property>

    </bean>

    <!--02.Set集合配置文件-->

    <bean id="set" class="cn.wgy.day01.entity.CollectionBean">

    <property ame="address">

    <set>

    <value>北京</value>

    <value>上海</value>

    </set>

    </property>

    </bean>

    <!--03.Map集合-->

    <bean id="map" class="cn.wgy.day01.entity.CollectionBean">

    <property name="map">

    <map>

    <entry key="nh">

    <key>

    <value>1</value>

    </key>

    <value>12</value>

    </entry>

    <entry>

    <key>

    <value>2</value>

    </key>

    <value>20</value>

    </entry>

    </map>

    </property>

    </bean>

    <bean id="props" class="cn.wgy.day01.entity.CollectionBean">

    <property ame="hobbies">

    <props>

    <prop key="f">足球</prop>

    <prop key="b">篮球</prop>

    </props>

    </property>

    </bean>

    <!--注入空字符串 -->

    <bean id="user2" class="cn.wgy.day01.entity.User">

    <property ame="email"><value></value></property>

    </bean>

    <!--注入null值-->

    <bean id="user3" class="cn.wgy.day01.entity.User">

    <property ame="email"><null/></property>

    </bean>

    了解详情请登陆昆明达内Java培训官网(km.Java.tedu.cn)!

    推荐文章

上一篇:Spring提供依赖注入的方式

下一篇:【昆明Java培训班】什么是AOP?

最新开班日期  |  更多

Java--零基础全日制班

Java--零基础全日制班

开班日期:12/29

Java--零基础业余班

Java--零基础业余班

开班日期:12/29

Java--周末提升班

Java--周末提升班

开班日期:12/29

Java--零基础周末班

Java--零基础周末班

开班日期:12/29

  • 网址:http://km .java.tedu.cn      地址:昆明市官渡区春城路62号证券大厦附楼6楼
  • 课程培训电话:186 8716 1620      qq:2066486918    全国服务监督电话:400-827-0010
  • 服务邮箱 ts@tedu.cn
  • 2001-2016 达内国际公司(TARENA INTERNATIONAL,INC.) 版权所有 京ICP证08000853号-56