• Spring装配bean


    创建对象之间协作关系的行为通常称为装配(wiring),这也是DI的本质。Spring提供了三种主要的装配机制。

    • 在XML中进行显式配置。
    • 在Java中进行显式配置。
    • 隐式的bean发现机制和自动装配。

    隐式的bean发现机制和自动装配

    Spring从两个角度来实现自动化装配:

    • 组件扫描(component scanning):Spring会自动发现应用上下文中所创建的bean。
    • 自动装配(autowiring):Spring自动满足bean之间的依赖。

    通过xml启动组件扫描(也可以通过java文件启动,我感觉不方便,不使用了):

    1. <context:component-scan base-package="com.zjf" />

    组件扫描会扫描上面配置目录下和子目录下的响应注解,然后注册为bean。自动转配也是通过注解来实现的。

    当一个 Bean 被自动检测到时,会根据那个扫描器的 BeanNameGenerator 策略生成它的 bean 名称。默认情况下,对于包含 value 属性的 @Component、 @Repository、 @Service 和 @Controller,会把value 取值作为 Bean 的名字。如果这个注解不包含 value 值或是其他被自定义过滤器发现的组件,默认 Bean 名称会是小写开头的类的简单名称。

    spring常用的注解(暂时不说Spring mvc的注解):

    • @Component

    泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。

    通过value属性指定bean的名字。如@Component(value="xx"),或者@Component("xx")。

    @Repository、@Service 和 @Controller是继承自@Component的,在现在的版本上,他们的用法没有任何差别。只是标识不同的层。以后的版本可能会有差别。

    • @Autowired

    默认按类型装配,如果我们想使用按名称装配,可以结合@Qualifier注解一起使用。

    如下:@Autowired @Qualifier("personDaoBean") 存在多个实例配合使用

    @Autowired 有一个required属性,定义是否必须,默认是true。

    • @Resource

    默认按名称装配。

    按照名称装配的方法:如果定义了name属性,那么按照name属性配置的名称去查找bean,如果没有定义name属性,那么是把属性名称首字母小写。

    如果按照名称装配没有找到,会按类型装配,跟Autowired一样。

    • @Scope注解 作用域
    • @Lazy(true) 表示延迟初始化
    • @Service用于标注业务层组件、
    • @Controller用于标注控制层组件
    • @Repository用于标注数据访问组件,即DAO组件。
    • @PostConstruct用于指定初始化方法(用在方法上)
    • @PreDestory用于指定销毁方法(用在方法上)
    • @DependsOn:定义Bean初始化及销毁时的顺序
    • @Primary:自动装配时当出现多个Bean候选者时,被注解为@Primary的Bean将作为首选者,否则将抛出异常
    • @PostConstruct 初始化注解
    • @PreDestroy 摧毁注解 默认 单例 启动就加载
    • @Async异步方法调用
    • @Scope用于指定scope作用域的(用在类上)

    这里的 scope 就是用来配置 spring bean 的作用域,它标识 bean 的作用域。

    在spring2.0之前bean只有2种作用域即:singleton(单例)、non-singleton(也称 prototype), Spring2.0以后,增加了session、request、global session三种专用于Web应用程序上下文的Bean。

    1、singleton 作用域

    当一个bean的 作用域设置为singleton, 那么Spring IOC容器中只会存在一个共享的bean实例,并且所有对bean的请求,只要id与该bean定义相匹配,则只会返回bean的同一实例。换言之,当把 一个bean定义设置为singleton作用域时,Spring IOC容器只会创建该bean定义的唯一实例。这个单一实例会被存储到单例缓存(singleton cache)中,并且所有针对该bean的后续请求和引用都 将返回被缓存的对象实例,这里要注意的是singleton作用域和GOF设计模式中的单例是完全不同的,单例设计模式表示一个ClassLoader中 只有一个class存在,而这里的singleton则表示一个容器对应一个bean,也就是说当一个bean被标识为singleton时 候,spring的IOC容器中只会存在一个该bean。

    配置实例: 

    <bean id="role" class="spring.chapter2.maryGame.Role" scope="singleton"/>

    或者

    <bean id="role" class="spring.chapter2.maryGame.Role" singleton="true"/>

    2、prototype

    prototype作用域部署的bean,每一次请求(将其注入到另一个bean中,或者以程序的方式调用容器的 getBean()方法)都会产生一个新的bean实例,相当与一个new的操作,对于prototype作用域的bean,有一点非常重要,那就是Spring不能对一个prototype bean的整个生命周期负责,容器在初始化、配置、装饰或者是装配完一个prototype实例后,将它交给客户端,随后就对该prototype实例不闻不问了。不管何种作用域,容器都会调用所有对象的初始化生命周期回调方法,而对prototype而言,任何配置好的析构生命周期回调方法都将不会被调用。 清除prototype作用域的对象并释放任何prototype bean所持有的昂贵资源,都是客户端代码的职责。(让Spring容器释放被singleton作用域bean占用资源的一种可行方式是,通过使用 bean的后置处理器,该处理器持有要被清除的bean的引用。)

    配置实例: 

    <bean id="role" class="spring.chapter2.maryGame.Role" scope="prototype"/>

    或者

    <beanid="role" class="spring.chapter2.maryGame.Role" singleton="false"/>

    3、request

    request表示该针对每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP request内有效,配置实例:

    request、session、global session使用的时候首先要在初始化web的web.xml中做如下配置:

    如果你使用的是Servlet 2.4及以上的web容器,那么你仅需要在web应用的XML声明文件web.xml中增加下述ContextListener即可: 

    <web-app>

    ...

    <listener>

    <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>

    </listener>

    ...

    </web-app>

    如果是Servlet2.4以前的web容器,那么你要使用一个javax.servlet.Filter的实现: 

    <web-app>

    ..

    <filter>

    <filter-name>requestContextFilter</filter-name>

    <filter-class>org.springframework.web.filter.RequestContextFilter</filter-class>

    </filter>

    <filter-mapping>

    <filter-name>requestContextFilter</filter-name>

    <url-pattern>/*</url-pattern>

    </filter-mapping>

    ...

    </web-app>

    接着既可以配置bean的作用域了: 

    <bean id="role" class="spring.chapter2.maryGame.Role" scope="request"/>

    4、session

    session作用域表示该针对每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP session内有效,配置实例:

    配置实例:

    和request配置实例的前提一样,配置好web启动文件就可以如下配置: 

    <bean id="role" class="spring.chapter2.maryGame.Role" scope="session"/>

    5、global session

    global session作用域类似于标准的HTTP Session作用域,不过它仅仅在基于portlet的web应用中才有意义。Portlet规范定义了全局Session的概念,它被所有构成某个 portlet web应用的各种不同的portlet所共享。在global session作用域中定义的bean被限定于全局portlet Session的生命周期范围内。如果你在web中使用global session作用域来标识bean,那么web会自动当成session类型来使用。

    在xml中显示配置:

    这种情况一般不能使用注解的情况下才会使用,不做深入学习,摘抄一篇文章备用。

    文章地址:http://www.cnblogs.com/le576169235/p/6203129.html

    (2)配置一个简单的bean

      <bean class="pojo.TestSpring" id="test"></bean>

    注:上例中id属性如果没有指定,这个bean将会根据全限定类名命名,在上例中,将会是"pojo.TestSpring#0"。其中#0为一个计数形式,用来区分其他同类型的bean,若声明了

    另外一个TestSpring,将会是"pojo.TestSpring#1"。

    (3)借助构造器注入属性

    constructor-arg节点

    上例中constructor-arg节点的顺序即为构造函数中参数列表的参数顺序,一一对应,类型对应错误则会抛出异常

    同时,该节点数目与要使用的构造函数的参数列表的参数个数必须一致。上例中注入的是对象类型,若要注入字面

    良,讲ref属性改为value即可,如

    此外,使用构造器注入属性除了使用constructor-arg节点外,还可以使用c命名空间,使用c命名空间可以减少配置文件的

    冗长,但是constructor-arg节点能做到的有些事情,c命名空间无法做到。

    c命名空间

    1.要使用c命名空间,必须要在xml文件顶部声明其模式,如下图所示。

    2.c命名空间格式

    c:cdplay-ref="play"

    c:c命名空间前缀 cdplay:构造器参数名 -ref:注入bean引用  ="play" :要注入的bean的ID

    c命名空间也可根据参数顺序注入属性,即顺序索引,因为XML不支持数字作为属性的第一个字符,所以前数字前加上一个下划线

     

    与constructor-arg参数一样,注入属性类型与数量,必须与使用的构造函数一致。

    若要通过c命名空间注入字面量,则如下图所示

    笔者所给出的样例类中并没有给出String,int等类型的属性,这里给出的字面量注入方式只作为样例师范,读者若要经行测试需要自己建立更优的样例类。

    (4)通过属性的set方法注入属性

    <property></property>节点

    其中name为属性名,ref为要注入的bean的Id

    与construstor-arg节点类似,若要注入字面量,将ref属性改为value

    p命名空间

    1.要使用p命名空间,需要在XML文件顶部配置其模式,如下图

    2.p命名空间格式

    p:cdplay-ref="play"

    p:p命名空间前缀 cdplay:构造器参数名 -ref:注入bean引用  ="play" :要注入的bean的ID

     

    p命名空间不能通过顺序索引注入属性

    与c命名空间类似,若要注入字面量,将-ref去掉。

    (5)集合类型属性的注入

       

    如上图所示,给出了list,map,set集合类型的注入方式,此外可借助util命名空间创建集合bean

    1.要使用util命名空间,需要在xml文件顶部配置其模式

    2.util:list

    util命名空间让集合能够像其他的bean一样被注入到其他bean中

    3.util-命名空间中的元素

     元素

    描述

    <util:constant>

    引用某个类型的Public static域,并将其暴露为bean

    <util:list>

    创建一个java.util.list类型的bean,其中包含值或引用

    <util:map>

    创建一个java.util.map类型的bean,其中包含值或引用

    <util:properties>

    创建一个java.util.Properties类型的bean

    <util:property-path>

    引用一个bean的属性(或内嵌属性),并将其暴露为bean

    <util:set>

    创建一个java.util.Set类型的bean,其中包含值或引用

    在java中显示装备:

    通过@Configuration 和@Bean 注解来实现,@Configuration把一个类作为一个IoC容器,它的某个方法头上如果注册了@Bean,就会作为这个Spring容器中的Bean。

    很少使用,不再赘述。

  • 相关阅读:
    [android开放篇] wifi-direct接口网址
    [adb 连接不上的原因] 汇总
    SharePoint 2010 master page 控件介绍(1)
    Sharepoint 2010 根据用户权限隐藏Ribbon菜单
    How to: Hide the Ribbon in SharePoint 2010
    sharepoint2010网站根据权限隐藏ribbon
    SharePoint 2010 master page 控件介绍(2):ribbon (一同事读听着像泪奔)
    SharePoint 2010 Ribbon的实现
    为SharePoint网站创建自定义导航菜单
    Sharepoint 2010 用VS定制Master,并且每个Web应用同一个Master
  • 原文地址:https://www.cnblogs.com/xiaolang8762400/p/7018709.html
Copyright © 2020-2023  润新知