Spring进阶运用

1.配置Bean的属性和依赖关系
组件与组件之间的耦合采用依赖注入管理;但对普通的JavaBean属性值,则直接在代码中设置。
1.1Bean的配置

     <beans>
        <bean id="唯一标识符" name="别名1,别名2" class="实现类的全限定类名"/>
     </beans>

1.2设置普通属性值

      <property name=" " value=" "/>

1.3配置合作者Bean

     <bean id="u" class=" "/>
     <bean id="user" class=" ">
       <property name="userDao">
         <ref bean="u"/>
       </property>
       <constructor-arg>
         <ref bean="u">
       </constructor-arg>
     </bean>
 !!被注入的类型只需要与注入目标中定义的类型兼容就可。

1.4注入集合值

     //Set<String>
     <property name="sets">
        <set>
          <value>1</value>
          <value>2</value>
        </set>
     </property>
     //List<String>
     <property name="lists">
        <list>
          <value>1</value>
          <value>2</value>
        </list>
     </property>
     //Map<String,String> <entry>中key值只能是String
     <property name="maps">
        <map>
          <entry key="1" value="1"></entry>
          <entry key="2" value="2"></entry>
        </map>
     </property>
     <property name="maps">
        <map>
          <entry>
            <key>
              <value>1</value>
            </key>
            <value>1</value>
            <key>
              <value>2</value>
            </key>
            <value>2</value>
          </entry>
        </map>
     </property> 

2.管理Bean的生命周期
Bean生命周期
Spring可以管理singleton作用域Bean的生命周期,可以精确的知道该Bean何时被创建,何时初始化完成,何
时被销毁。
Spring仅负责创建prototype作用域的Bean,创建完后完全交给客户端代码管理。
两个重要生命周期时刻:postinitiation(初始化后)和predestruction(销毁前)。
2.1Spring容器中Bean的作用域
Spring3.0中支持的5种作用域:
(1)Singleton:单例模式,在容器中只有一个实例,无论多少Bean引用他,都只有一个对象;
(2)Prototype:原型模式,每次通过容器获取Bean时,都会创建一个新的实例;
(3)Request:针对每次HTTP请求都会产生一个新的Bean,仅在当前HTTP request内有效;
(4)Session:针对每次HTTP请求都会产生一个新的Bean,仅在当前HTTP session内有效;
(5)Global session:类似标准HTTP Session作用域,但仅仅在基于portlet的web应用中有效。

      //scope默认为singleton
      <bean id=" " class=" " scope="singleton|prototype|request|session|global session"/>
  如果Bean使用了有限的资源,如数据库、网络连接等,则多个实例的创建会浪费有限的资源,此时应将Bean设置为
  singleton。

2.2Bean的实例化
当一个Bean实例化时,往往需要执行一些初始化工作;不再使用时,需要从容器中删除他。
(1)指定初始化方法

        <bean id="bean1" class="com.bean.simpleBean" init-method="init"
          <property name="name" value="xiaoming"/>
        </bean>
  Spring完成依赖注入后,自动调用init()方法。

(2)实现InitializingBean接口(侵入式设计,不推荐使用)
一旦某个Bean实现了InitializingBean接口,那么这个Bean的代码就与Spring耦合到一起了。该接口只定义
了一个afterPropertiesSet方法。
凡是继承了InitializingBean接口的类,初始化Bean时都会执行其afterPropertiesSet方法。
!!可以和指定初始化方法 同时使用,此时先执行afterPropertiesSet()方法,再执行init-method属性指定
方法。
Spring容器可以自动检测Bean中是否实现了特定生命周期接口,若实现某个生命周期接口,则需执行相应
的生命周期方法。
2.3Bean的销毁
Spring提供了两种方法在Bean实例销毁之前执行指定的动作:使用destroy-method属性和实现
DisposableBean接口。
(1)使用关闭钩子(shutdown hook)
只需要调用在AbstractApplicationContext中提供的registerShutdownHook()方法

         public static void main(String[] args){
            AbstractApplicationContext ctx = new 
            ClassPathXmlApplicationContext("beans.xml");
            ctx.getBean(" ");
            //为Spring容器注册关闭钩子
            ctx.registerShutdownHook();
         }
     程序会在退出JVM之前关闭Spring ApplicationContext容器,并在关闭之前调用singleton作用域中Bean的
     析构回调方法。

(2)Bean销毁时执行析构方法
可以在Bean中定义一个普通的析构方法,然后在XML配置文件中通过destroy-method属性指定其方法
名。Spring会在销毁单例前调用此方法执行一些清理和释放工作。

        <bean id="bean1" class="com.bean.simpleBean" destroy-method="close"
          <property name="name" value="xiaoming"/>
        </bean>
        //Spring会在销毁bean1实例前自动调用simpleBean类中的close()方法。       

(3)实现DisposableBean接口(侵入式设计)
该接口只有一个方法:void destroy() throws Exception,Bean实例被销毁前执行的方法。
2.4使用方法注入
singleton Bean依赖的一直是最开始(初始化时)的Bean实例。
lookup方法注入利用了Spring容器重写Bean中抽象方法或具体方法的能力,从而返回指定名字的Bean实
例,常用来获取一个non-singleton对象。
!!Spring方法注入需要用到CGLIB的动态代理功能,需要将CGLIB库的JAR包导入到项目中。

        public abstract MyHelper getMyHelper();
    @Override
    public MyHelper getHelper(){
        return getMyHelper();
    }
        <bean id="helper" class="com.deciphering.bean.MyHelper" scope="prototype">
        </bean> 
        <bean id="abstractLookupBean" class="com.deciphering.bean.AbstractLookupDemo">
        <lookup-method name="getMyHelper" bean="helper"/>
        </bean>

3.让Bean可以感知Spring容器
3.1使用BeanNameAware接口
该接口仅有一个方法:setBeanName(String name),name参数为Bean的id.Bean属性设置完后,初始化回调方法之前,setBeanName回调方法会先被调用。

    public class SimpleBean implements InitializingBean, BeanNameAware{
    private String beanName;
    ...
    @Override
    public void setBeanName(String beanName) {
        this.beanName = beanName;
        System.out.println("回调setBeanName方法获得BeanName "+ beanName);
    }
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println(beanName+"初始化,调用afterPropertiesSet()...");   
    }
   }
   //先调用setBeanName(String beanName),再调用afterPropertiesSet()

3.2使用BeanFactoryAware接口、ApplicationContextAware接口
BeanFactoryAware接口只有一个方法:setBeanFactory(BeanFactory beanFactory);
实现该接口让Bean拥有了直接访问容器的能力,导致代码和Spring接口耦合在一起

     public class SimpleBean implements InitializingBean, BeanFactoryAware{
    private BeanFactory Factory;
    ...
    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.Factory = beanFactory;
        System.out.println("获得容器: "+Factory);
    }
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("初始化完成,调用afterPropertiesSet()...");  
    }
     }
     //先调用setBeanFactory(BeanFactory beanFactory),再调用afterPropertiesSet()
!!Spring容器完成依赖关系注入之后会回调setBeanFactory()方法,此时应用程序可获得创建该Bean的BeanFactory引用,程序可以保存该引用并利用其做一些处理。
另外,类似,还有ApplicationContextAware接口,可获得ApplicationContext容器的引用。

4.Spring国际化支持
getMessage()的重载方法:
getMessage(String,Object[],Locale);
getMessage(String,Object[],String Locale);
getMessage(MessageSourceResolvable,Locale)

    public class SimpleBean {
    public static void main(String[] args){
        //实例化ApplicationContext
        ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
        String [] a = {"读者"};
        //使用getMessage方法获得本地化信息。
        //返回计算机环境默认的Locale
        String hello = ctx.getMessage("hello", a, Locale.getDefault());
        Object[] b = { new Date() };
        String now = ctx.getMessage("now", b, Locale.getDefault());
        //将两条本地化信息打印出来
        System.out.println(hello);      
        System.out.println(now);

        //认为设置成英文环境
        hello = ctx.getMessage("hello", a, Locale.US);
        now = ctx.getMessage("now", b, Locale.US);
        //将两条英文信息打印出来
        System.out.println(hello);      
        System.out.println(now);

        //认为设置成中文环境
        hello = ctx.getMessage("hello", a, Locale.CHINA);
        now = ctx.getMessage("now", b, Locale.CHINA);
        //将两条中文信息打印出来
        System.out.println(hello);      
        System.out.println(now);
    }
   }
   //即使在英文环境下,“读者”也不能变成英文,因为是写在代码中而不是从资源文件中获取的。
    <!-- id="messageSource"不变 -->
    <bean id="messageSource"   
    class="org.springframework.context.support.ResourceBundleMessageSource">
        <property name="basenames" >
            <list>
                <value>message</value>
                <!--
                如果有多个资源文件,全部列举在此
                -->
            </list>
        </property>
    </bean> 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值