Spring IOC

1.Spring框架概述

1.1 什么是Spring

Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson 在其著作Expert One-On-One J2EE Development and Design中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 J2EE 应用程序开发提供集成的框架。Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。Spring的核心是控制反转(IoC)和面向切面(AOP)。

1.2 Spring的特点   

1.方便解耦,简化开发
通过Spring提供的IoC容器,我们可以将对象之间的依赖关系交由Spring进行控制,避免硬编码所造成的过度程序耦合。有了Spring,用户不必再为单实例模式类、属性文件解析等这些很底层的需求编写代码,可以更专注于上层的应用。
2.AOP编程的支持
通过Spring提供的AOP功能,方便进行面向切面的编程,许多不容易用传统OOP实现的功能可以通过AOP轻松应付。
3.声明事物的支持
在Spring中,我们可以从单调烦闷的事务管理代码中解脱出来,通过声明式方式灵活地进行事务的管理,提高开发效率和质量。
4.方便程序的测试
可以用非容器依赖的编程方式进行几乎所有的测试工作,在Spring里,测试不再是昂贵的操作,而是随手可做的事情。例如:Spring对Junit4支持,可以通过注解方便的测试Spring程序。
5.方便集成各种优秀框架
Spring不排斥各种优秀的开源框架,相反,Spring可以降低各种框架的使用难度,Spring提供了对各种优秀框架(如Struts,Hibernate、Hessian、Quartz)等的直接支持。
6.降低Java EE API的使用难度
Spring对很多难用的Java EE API(如JDBC,JavaMail,远程调用等)提供了一个薄薄的封装层,通过Spring的简易封装,这些Java EE API的使用难度大为降低。

1.3 Spring的优势

优点:
1.低侵入式设计,代码污染极低
2.独立于各种应用服务器,基于Spring框架的应用,可以真正实现Write Once,Run Anywhere的承诺
3.Spring的DI机制降低了业务对象替换的复杂性,提高了组件之间的解耦
4.Spring的AOP支持允许将一些通用任务如安全、事务、日志等进行集中式管理,从而提供了更好的复用
5.Spring的ORM和DAO提供了与第三方持久层框架的良好整合,并简化了底层的数据库访问
6.Spring并不强制应用完全依赖于Spring,开发者可自由选用Spring框架的部分或全部

1.4 框架特征与功能

轻量:从大小与开销两方面而言Spring都是轻量的。完整的Spring框架可以在一个大小只有1MB多的JAR文件里发布。并且Spring所需的处理开销也是微不足道的。此外,Spring是非侵入式的:典型地,Spring应用中的对象不依赖于Spring的特定类。

控制反转Ioc:Spring通过一种称作控制反转(IoC)的技术促进了低耦合。当应用了IoC,一个对象依赖的其它对象会通过被动的方式传递进来,而不是这个对象自己创建或者查找依赖对象。你可以认为IoC与JNDI相反——不是对象从容器中查找依赖,而是容器在对象初始化时不等对象请求就主动将依赖传递给它。

面向切面Aop:Spring提供了面向切面编程的丰富支持,允许通过分离应用的业务逻辑与系统级服务(例如审计(auditing)和事务(transaction)管理)进行内聚性的开发。应用对象只实现它们应该做的——完成业务逻辑——仅此而已。它们并不负责(甚至是意识)其它的系统级关注点,例如日志或事务支持。

容器:Spring包含并管理应用对象的配置和生命周期,在这个意义上它是一种容器,你可以配置你的每个bean如何被创建——基于一个可配置原型(prototype),你的bean可以创建一个单独的实例或者每次需要时都生成一个新的实例——以及它们是如何相互关联的。然而,Spring不应该被混同于传统的重量级的EJB容器,它们经常是庞大与笨重的,难以使用。

框架:Spring可以将简单的组件配置、组合成为复杂的应用。在Spring中,应用对象被声明式地组合,典型地是在一个XML文件里。Spring也提供了很多基础功能(事务管理、持久化框架集成等等),将应用逻辑的开发留给了你。

MVC:Spring的作用是整合,但不仅仅限于整合,Spring 框架可以被看做是一个企业解决方案级别的框架,Spring MVC是一个非常受欢迎的轻量级Web框架。

 

1.5 Spring的组成

Spring 框架是一个分层架构,由 7 个定义良好的模块组成。Spring 模块构建在核心容器之上,核心容器定义了创建、配置和管理 bean 的方式

组成 Spring 框架的每个模块(或组件)都可以单独存在,或者与其他一个或多个模块联合实现。每个模块的功能如下:

  • 核心容器:核心容器提供 Spring 框架的基本功能。核心容器的主要组件是 BeanFactory,它是工厂模式的实现。BeanFactory 使用控制反转(IOC) 模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。
  • Spring 上下文:Spring 上下文是一个配置文件,向 Spring 框架提供上下文信息。Spring 上下文包括企业服务,例如 JNDI、EJB、电子邮件、国际化、校验和调度功能。
  • Spring AOP:通过配置管理特性,Spring AOP 模块直接将面向方面的编程功能集成到了 Spring 框架中。所以,可以很容易地使 Spring 框架管理的任何对象支持 AOP。Spring AOP 模块为基于 Spring 的应用程序中的对象提供了事务管理服务。通过使用 Spring AOP,不用依赖 EJB 组件,就可以将声明性事务管理集成到应用程序中。
  • Spring DAO:JDBC DAO 抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理和不同数据库供应商抛出的错误消息。异常层次结构简化了错误处理,并且极大地降低了需要编写的异常代码数量(例如打开和关闭连接)。Spring DAO 的面向 JDBC 的异常遵从通用的 DAO 异常层次结构。
  • Spring ORM:Spring 框架插入了若干个 ORM 框架,从而提供了 ORM 的对象关系工具,其中包括 JDO、Hibernate 和 iBatis SQL Map。所有这些都遵从 Spring 的通用事务和 DAO 异常层次结构。
  • Spring Web 模块:Web 上下文模块建立在应用程序上下文模块之上,为基于 Web 的应用程序提供了上下文。所以,Spring 框架支持与 Jakarta Struts 的集成。Web 模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。
  • Spring MVC 框架:MVC 框架是一个全功能的构建 Web 应用程序的 MVC 实现。通过策略接口,MVC 框架变成为高度可配置的,MVC 容纳了大量视图技术,其中包括 JSP、Velocity、Tiles、iText 和 POI。

其中Spring的主要核心是:1.控制反转(IoC,Inversion of Control)2.面向切面变成(AOP)

控制反转的作用:解除类与类之间的关系耦合

面向切面编程(AOP)作用:为了解除业务逻辑耦合,例如耦合或者数据业务逻辑日志业务

2.控制反转(IoC)

控制反转IoC(Inversion of Control),是一种设计思想。没有IoC的程序中我们使用面向对象编程对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序自己控制,控制反转后将对象的创建转移给第三方,个人认为所谓控制反转就是:获得依赖对象的方式反转了。

耦合指的是两个类之间的联系的紧密程度;
强耦合:类之间存在着直接关系
弱耦合:在两个类的中间加入一层,将原来的直接关系变成间接关系,使得两个类对中间层是强耦合,两类之间变为弱耦合

IoC是Spring框架的核心内容,使用多种方式完美的实现了IoC,可以使用XML配置,也可以使用注解,新版本的Spring也可以零配置实现IoC。Spring容器在初始化时先读取配置文件,根据配置文件或元数据创建与组织对象存入容器中,程序使用时再从Ioc容器中取出需要的对象。

采用XML方式配置Bean的时候,Bean的定义信息是和实现分离的,而采用注解的方式可以把两者合为一体,Bean的定义信息直接以注解的形式定义在实现类中,从而达到了零配置的目的。

控制反转是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式。在Spring中实现控制反转的是IoC容器,其实现方法是依赖注入(Dependency Injection,DI)。

注:IoC和DI的关系并不是一个,类似于接口和实现类的区别,IoC是一种设计思想,DI是IoC的一种实现,DI也称为依赖注入,在Spring中可以通过@Autowired注解将Spring容器中的对象注入到指定的位置。

3.属性注入的方式

3.1 使用set方法进行注入

Users类:

package com.cqucc.pojo;

public class Users {
    //创建属性
    private Integer userid;
    private String usernama;
    private String password;
    //1、set方法注入
    //创建对应的set方法
    public void setUserid(Integer userid) {
        this.userid = userid;
    }

    public void setUsernama(String usernama) {
        this.usernama = usernama;
    }

    public void setPassword(String password) {
        this.password = password;
    }
  @Override
    public String toString() {
        return "Users{" +
                "userid=" + userid +
                ", usernama='" + usernama + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

beans1.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">
        <!-- 一、set方法注入属性-->
    
        <!-- 1、配置对象的创建-->
       <bean id="users" class="com.cqucc.pojo.Users">
            <!-- 2、使用property完成属性注入
                    name:类里面的属性名称
                    value:向属性中注入的值
            -->
              <property name="userid" value="1"></property>
              <property name="usernama" value="admin"></property>
            <!--属性值包含特殊符号
                1.把<>进行转义
                2.把带特殊符号的内容写到CDATA
            -->
              <property name="password">
                <value><![CDATA[<<北京>>]]></value>
              </property>
        </bean>
</beans>

测试代码:

 @Test
    public void Tses01(){
        ApplicationContext context = new ClassPathXmlApplicationContext("beans1.xml");

        Users users = context.getBean("users", Users.class);

        System.out.println(users);
    }

输出结果: 

3.2 使用有参构造函数进行注入

 Users类:

package com.cqucc.pojo;

public class Users {

    private Integer userid;
    private String usernama;
    private String password;
    public Users (){
        System.out.println("这是无参构造方法");
    }

    public Users(Integer userid, String usernama, String password) {
        System.out.println("这是有参构造方法");
        this.userid = userid;
        this.usernama = usernama;
        this.password = password;
    }
    
    @Override
    public String toString() {
        return "Users{" +
                "userid=" + userid +
                ", usernama='" + usernama + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

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


        <!--二、有参构造注入属性-->
        <bean id="users2" class="com.cqucc.pojo.Users">
            <constructor-arg name="usernama" value=" root"></constructor-arg>
            <constructor-arg name="password" value="1234"></constructor-arg>
            <constructor-arg name="userid" value="2"></constructor-arg>
        </bean>
    
</beans>

测试代码:

    @Test
    public void Tses02(){
        ApplicationContext context = new ClassPathXmlApplicationContext("beans1.xml");


        Users users = context.getBean("users2", Users.class);

        System.out.println(users);
    }

测试结果: 


3.3 使用p名称空间注入

第一步:添加p名称空间 xmlns:p="http://www.springframework.org/schema/p"
第二步:进行属性注入,在beans标签里。

Users类:

package com.cqucc.pojo;

public class Users {
    //使用p名称空间注入属性
    private Integer userid;
    private String usernama;
    private String password;
    //p名称空间注入
    public void setUserid(Integer userid) {
        this.userid = userid;
    }

    public void setUsernama(String usernama) {
        this.usernama = usernama;
    }

    public void setPassword(String password) {
        this.password = password;
    }
  @Override
    public String toString() {
        return "Users{" +
                "userid=" + userid +
                ", usernama='" + usernama + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

beans1.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" xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

       <bean id="users" class="com.cqucc.pojo.Users" p:usernama="qq" p:userid="1002" p:password="password"></bean>
       
</beans>

 测试代码:

    @Test
    public void Tses03(){
        ApplicationContext context = new ClassPathXmlApplicationContext("beans1.xml");
        
        Users users = context.getBean("users", Users.class);

        System.out.println(users);
    }

测试结果: 

3.4 注入集合属性

Collection 类

package com.cqucc.pojo;


import java.util.List;
import java.util.Set;
import java.util.Map;


public class Collection {
    private List<String> list;
    private Set<String> set;
    private Map<String,String> map;
    private Integer[] nums;

    public List<String> getList() {
        return list;
    }

    public void setList(List<String> list) {
        this.list = list;
    }

    public Set<String> getSet() {
        return set;
    }

    public void setSet(Set<String> set) {
        this.set = set;
    }

    public Map<String, String> getMap() {
        return map;
    }

    public void setMap(Map<String, String> map) {
        this.map = map;
    }

    public Integer[] getNums() {
        return nums;
    }

    public void setNums(Integer[] nums) {
        this.nums = nums;
    }
}

beans2.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" xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

        <bean class="com.cqucc.pojo.Collection" name="collection">
            <property name="nums">
                <array>
                    <value>1</value>
                    <value>2</value>
                    <value>3</value>
                </array>
            </property>
            <property name="list">
                <list>
                    <value>list元素1</value>
                    <value>list元素2</value>
                    <value>list元素3</value>
                </list>
            </property>
            <property name="map">
                <map>
                    <entry key="cn" value="中国"></entry>
                    <entry key="en" value="英国"></entry>
                    <entry key="us" value="美国"></entry>
                </map>
            </property>
            <property name="set">
                <set>
                    <value>set元素1</value>
                    <value>set元素2</value>
                    <value>set元素3</value>
                </set>
            </property>
        </bean>

        <bean id="emp1" class="com.cqucc.pojo.Emp" p:empid="0001" p:empname="tone" p:empsex="男"></bean>
        <bean id="emp2" class="com.cqucc.pojo.Emp" p:empid="0002" p:empname="zhang" p:empsex="男"></bean>
        <bean id="emp3" class="com.cqucc.pojo.Emp" p:empid="0003" p:empname="wang" p:empsex="女"></bean>

        <bean id="dept" class="com.cqucc.pojo.Dept">
            <property name="list">
                <list>
                    <ref bean="emp1"></ref>
                    <ref bean="emp2"></ref>
                    <ref bean="emp3"></ref>
                </list>
            </property>
        </bean>
</beans>

 测试代码:

    @Test
    public void Tses04(){
        ApplicationContext context = new ClassPathXmlApplicationContext("beans2.xml");


        Collection collection = context.getBean("collection", Collection.class);

        System.out.println(Arrays.toString(collection.getNums()));
        System.out.println(collection.getList());
        System.out.println(collection.getMap());
        System.out.println(collection.getSet());
    }

测试结果: 

4. Spring中的bean 

bean是由IoC容器初始化、装配及管理的对象,除此之外,bean就与应用程序中的其他对象没有什么区别了。而bean的定义以及bean相互间的依赖关系将通过配置元数据来描述。Spring中的bean默认都是单例的,对于Web应用来说,Web容器对于每个用户请求都创建一个单独的Sevlet线程来处理请求,引入Spring框架之后,每个Action都是单例的,那么对于Spring托管的单例Service Bean,Spring的单例是基于BeanFactory也就是Spring容器的,单例Bean在此容器内只有一个,Java的单例是基于JVM,每个JVM内只有一个实例
 

4.1 bean的作用域

创建一个bean定义,其实质是用该bean定义对应的类来创建真正实例的“配方”。把bean定义看成一个配方很有意义,它与class很类似,只根据一张“处方”就可以创建多个实例。不仅可以控制注入到对象中的各种依赖和配置值,还可以控制该对象的作用域。这样可以灵活选择所建对象的作用域,而不必在Java Class级定义作用域。Spring Framework支持五种作用域,分别阐述如下表。


五种作用域中,request、session和global session三种作用域仅在基于web的应用中使用(不必关心你所采用的是什么web应用框架),只能用在基于web的Spring ApplicationContext环境。

(1)当一个bean的作用域为Singleton,那么Spring IoC容器中只会存在一个共享的bean实例,并且所有对bean的请求,只要id与该bean定义相匹配,则只会返回bean的同一实例。Singleton是单例类型,就是在创建起容器时就同时自动创建了一个bean的对象,不管你是否使用,他都存在了,每次获取到的对象都是同一个对象。注意,Singleton作用域是Spring中的缺省作用域。要在XML中将bean定义成singleton,可以这样配置:

<bean id="ServiceImpl" class="cn.csdn.service.ServiceImpl" scope="singleton">

(2)当一个bean的作用域为Prototype,表示一个bean定义对应多个对象实例。Prototype作用域的bean会导致在每次对该bean请求(将其注入到另一个bean中,或者以程序的方式调用容器的getBean()方法)时都会创建一个新的bean实例。Prototype是原型类型,它在我们创建容器的时候并没有实例化,而是当我们获取bean的时候才会去创建一个对象,而且我们每次获取到的对象都不是同一个对象。根据经验,对有状态的bean应该使用prototype作用域,而对无状态的bean则应该使用singleton作用域。在XML中将bean定义成prototype,可以这样配置:

<bean id="account" class="com.foo.DefaultAccount" scope="prototype"/>  
 <!--或者-->
<bean id="account" class="com.foo.DefaultAccount" singleton="false"/> 

(3)当一个bean的作用域为Request,表示在一次HTTP请求中,一个bean定义对应一个实例;即每个HTTP请求都会有各自的bean实例,它们依据某个bean定义创建而成。该作用域仅在基于web的Spring ApplicationContext情形下有效。考虑下面bean定义:

<bean id="loginAction" class=com.foo.LoginAction" scope="request"/>

针对每次HTTP请求,Spring容器会根据loginAction bean的定义创建一个全新的LoginAction bean实例,且该loginAction bean实例仅在当前HTTP request内有效,因此可以根据需要放心的更改所建实例的内部状态,而其他请求中根据loginAction bean定义创建的实例,将不会看到这些特定于某个请求的状态变化当处理请求结束,request作用域的bean实例将被销毁。

(4)当一个bean的作用域为Session,表示在一个HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。考虑下面bean定义:

<bean id="userPreferences" class="com.foo.UserPreferences" scope="session"/>


针对某个HTTP Session,Spring容器会根据userPreferences bean定义创建一个全新的userPreferences bean实例,且该userPreferences bean仅在当前HTTP Session内有效。与request作用域一样,可以根据需要放心的更改所创建实例的内部状态,而别的HTTP Session中根据userPreferences创建的实例,将不会看到这些特定于某个HTTP Session的状态变化。当HTTP Session最终被废弃的时候,在该HTTP Session作用域内的bean也会被废弃掉。

(5)当一个bean的作用域为Global Session,表示在一个全局的HTTP Session中,一个bean定义对应一个实例。典型情况下,仅在使用portlet context的时候有效。该作用域仅在基于web的Spring ApplicationContext情形下有效。考虑下面bean定义:

<bean id="user" class="com.foo.Preferences "scope="globalSession"/>

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


4.2 bean的生命周期

创建: 在Spring 容器初始化时候,创建单例对象,如果设置了init-method属性,则在创建对象以后调用初始化方法.

使用: 每次调用 getBean(String id,Class cla) 时候,返回的都是同一个对象.

 销毁: 在Spring 容器关闭的时候,Spring会自动销毁单例对象,如果指定了destory-method属性,则会在销毁之前执行 销毁 方法.


 BeansLife类

package com.cqucc.pojo;

public class BeansLife {
    private String name;
    public BeansLife(){
        System.out.println("无参构造方法");
    }

    public void setName(String name) {
        this.name = name;
        System.out.println("set方法");
    }
    public  void init(){
        System.out.println("init方法");
    }
    public void destroy(){
        System.out.println("destroy方法");
    }
}
BeansProcesson类
package com.cqucc.pojo;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

public class BeansProcesson implements BeanPostProcessor {
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("初始化之后");
        return bean;
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("初始化之前");
        return bean;
    }
}

beans.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" xmlns:p="http://www.springframework.org/schema/p"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util https://www.springframework.org/schema/util/spring-util.xsd">

        <bean id="beanslife" class="com.cqucc.pojo.BeansLife" init-method="init" destroy-method="destroy"></bean>

        <bean id="beanslife2" class="com.cqucc.pojo.BeansProcesson"></bean>
</beans>

没使用BeanPostProcessor测试代码:

    @Test
    public void Tses13(){
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans5.xml");
        System.out.println("======加载配置文件======");
        BeansLife beanslife = context.getBean("beanslife", BeansLife.class);
        System.out.println("------从Spring容器中获取对象-------");
        System.out.println(beanslife);

        context.close();
    }

没使用BeanPostProcessor测试结果:

 使用BeanPostProcessor测试代码:

    @Test
    public void Tses14(){
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans5.xml");
        System.out.println("======加载配置文件======");
        BeansLife beanslife = context.getBean("beanslife", BeansLife.class);
        System.out.println("------从Spring容器中获取对象-------");
        System.out.println(beanslife);

        context.close();
    }

 使用BeanPostProcessor测试结果:

 

Bean实例生命周期的执行过程如下:

  • Spring对bean进行实例化,默认bean是单例;
  • Spring对bean进行依赖注入;
  • 如果bean实现了BeanNameAware接口,Spring将bean的名称传给setBeanName()方法;
  • 如果bean实现了BeanFactoryAware接口,Spring将调用setBeanFactory()方法,将BeanFactory实例传进来;
  • 如果bean实现了ApplicationContextAware接口,它的setApplicationContext()方法将被调用,将应用上下文的引用传入到bean中;
  • 如果bean实现了BeanPostProcessor接口,它的postProcessBeforeInitialization()方法将被调用;
  • 如果bean中有方法添加了@PostConstruct注解,那么该方法将被调用;
  • 如果bean实现了InitializingBean接口,spring将调用它的afterPropertiesSet()接口方法,类似的如果bean使用了init-method属性声明了初始化方法,该方法也会被调用;
  • 如果在xml文件中通过<bean>标签的init-method元素指定了初始化方法,那么该方法将被调用;
  • 如果bean实现了BeanPostProcessor接口,它的postProcessAfterInitialization()接口方法将被调用;
  • 此时bean已经准备就绪,可以被应用程序使用了,他们将一直驻留在应用上下文中,直到该应用上下文被销毁;
  • 如果bean中有方法添加了@PreDestroy注解,那么该方法将被调用;
  • 若bean实现了DisposableBean接口,spring将调用它的distroy()接口方法。同样的,如果bean使用了destroy-method属性声明了销毁方法,则该方法被调用
     

 4.3 spring 中获取bean的两种方式

方法一:在初始化时保存ApplicationContext对象
代码: ApplicationContext ac = new FileSystemXmlApplicationContext(“applicationContext.xml”); ac.getBean(“beanId”); 说明:这种方式适用于采用Spring框架的独立应用程序,需要程序通过配置文件手工初始化Spring的情况。

方法二:通过Spring提供的工具类获取ApplicationContext对象 代码:

import org.springframework.web.context.support.WebApplicationContextUtils;

ApplicationContext ac1 = WebApplicationContextUtils.getRequiredWebApplicationContext(ServletContext sc);

ApplicationContext ac2 = WebApplicationContextUtils.getWebApplicationContext(ServletContext sc);

ac1.getBean(“beanId”);

ac2.getBean(“beanId”);

说明: 这种方式适合于采用Spring框架的B/S系统,通过ServletContext对象获取ApplicationContext对象,然后在通过它获取需要的类实例。

上面两个工具方式的区别是,前者在获取失败时抛出异常,后者返回null。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值