Spring(三)Bean繼續入門

來源:互聯網
上載者:User

標籤:指定   cep   frame   text   classpath   java   ngx   名稱   使用   

一、Aware相關介面

對於應用程式來說,應該盡量減少對Sping Api的耦合程度,然而有些時候為了運用Spring所提供的一些功能,有必要讓Bean瞭解Spring容器對其進行管理的細節資訊,如讓Bean知道在容器中是以那個名稱被管理的,或者讓Bean知道BeanFactory或者ApplicationContext的存在,也就是產讓該Bean可以取得BeanFactory或者ApplicationContext的執行個體,如果Bean可以意識到這些對象,那麼就可以在Bean的某些動作發生時,做一些如事件發布等操作。

1.1、Spring提供一些Aware介面:

beanNameAware介面:如果某個bean需要訪問設定檔中本身bean的id屬性,這個Bean類通過實現該介面,在依賴關係確定之後,初始化方法之前,提供回調自身的能力,從而獲得本身bean的id屬性,該介面提供了void setBeanName(String name)方法實現,需要指出的是該方法的name參數就是該bean的id屬性,加調該setBeanName方法可以讓bean擷取得自身的id屬性

BeanFactoryAware介面:實現了BeanFactoryAware介面的bean,可以直接通過beanfactory來訪問spring的容器,當該bean被容器建立以後,會有一個相應的beanfactory的執行個體引用,該 介面有一個方法void setBeanFactory(BeanFactory beanFactory)方法通過這個方法的參數建立它的BeanFactory執行個體,實現了BeanFactoryAware介面,就可以讓Bean擁有訪問Spring容器的能力。缺點:導致代碼與spring的api耦合在一起,這種方式不推薦。

ApplicationContextAware介面:在Bean類被初始化後,將會被注入applicationContext執行個體,該介面有一個方法,setApplicationContext(ApplicationContext context),使用其參數context用來建立它的applicationContext執行個體,缺點:導致代碼與spring的api耦合在一起,這種方式不推薦。

1.2、beanNameAware介面:
package com.pb.entity;import org.springframework.beans.factory.BeanNameAware;/* * 實體類實現init方法和BeanNameAware介面 */public class Hello implements BeanNameAware{    @Override    public void setBeanName(String arg0) {        System.out.println("回調setBeanName方法  id屬性是"+arg0);            }    public void init(){        System.out.println("正在執行初始化方法init");    }}

 applicationContext.xml

<bean id="hello" class="com.pb.entity.Hello" init-method="init"></bean>

  測試類別:

package com.pb.demo;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import com.pb.entity.Hello;public class HelloTest {    public static void main(String[] args) {        ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");        Hello hello=context.getBean("hello",Hello.class);    }}

  結果:

回調setBeanName方法  id屬性是hello正在執行初始化方法init

  

1.3、BeanFactoryAware介面:  
package com.pb.entity;import org.springframework.beans.BeansException;import org.springframework.beans.factory.BeanFactory;import org.springframework.beans.factory.BeanFactoryAware;import org.springframework.beans.factory.BeanNameAware;/* * 實體類實現init方法和BeanNameAware介面 */public class Hello implements BeanNameAware,BeanFactoryAware{    private BeanFactory bf;    @Override    public void setBeanName(String arg0) {        System.out.println("回調setBeanName方法  id屬性是"+arg0);            }    public void init(){        System.out.println("正在執行初始化方法init");    }        /*     * 重寫setBeanFactory方法     * @see org.springframework.beans.factory.BeanFactoryAware#setBeanFactory(org.springframework.beans.factory.BeanFactory)     */    @Override    public void setBeanFactory(BeanFactory arg0) throws BeansException {        this.bf=arg0;            }    public BeanFactory getBf() {        return bf;    }}

  

設定檔不變

測試類別:

package com.pb.demo;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import com.pb.entity.Hello;public class HelloTest {    public static void main(String[] args) {        ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");        Hello hello=context.getBean("hello",Hello.class);        System.out.println("得到beanFactory對象 "+hello.getBf());    }}

  結果:

回調setBeanName方法  id屬性是hello正在執行初始化方法init得到beanFactory對象 org.s[email protected]3dc0bb: defining beans [hello]; root of factory hierarchy

  
1.4、ApplicationContextAware介面:

package com.pb.entity;import org.springframework.beans.BeansException;import org.springframework.beans.factory.BeanFactory;import org.springframework.beans.factory.BeanFactoryAware;import org.springframework.beans.factory.BeanNameAware;import org.springframework.context.ApplicationContext;import org.springframework.context.ApplicationContextAware;/* * 實體類實現init方法和BeanNameAware介面 */public class Hello implements BeanNameAware,BeanFactoryAware,ApplicationContextAware{    private BeanFactory bf;    private ApplicationContext context;    @Override    public void setBeanName(String arg0) {        System.out.println("回調setBeanName方法  id屬性是"+arg0);            }    public void init(){        System.out.println("正在執行初始化方法init");    }        /*     * 重寫setBeanFactory方法     * @see org.springframework.beans.factory.BeanFactoryAware#setBeanFactory(org.springframework.beans.factory.BeanFactory)     */    @Override    public void setBeanFactory(BeanFactory arg0) throws BeansException {        this.bf=arg0;            }    public BeanFactory getBf() {        return bf;    }    @Override    public void setApplicationContext(ApplicationContext arg0)            throws BeansException {        this.context=arg0;            }    public ApplicationContext getContext() {        return context;    }}

  

設定檔不變

測試類別

package com.pb.demo;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import com.pb.entity.Hello;public class HelloTest {    public static void main(String[] args) {        ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");        Hello hello=context.getBean("hello",Hello.class);        System.out.println("得到beanFactory對象 "+hello.getBf());        System.out.println("得到的applicationContext對象:"+hello.getContext());    }}

  結果:

回調setBeanName方法  id屬性是hello正在執行初始化方法init得到beanFactory對象 org.s[email protected]3dc0bb: defining beans [hello]; root of factory hierarchy得到的applicationContext對象:org[email protected]1d04653: startup date [Wed Apr 08 00:43:06 CST 2015]; root of context hierarchy

  

二、BeanPostProcessor類 和BeanFactoryPostProcessor

對容器中的Bean進行處理

實現BeanPostProcessor介面Bean後處理器

public Object postProcessAfterInitialization(Object arg0, String arg1);在bean初始化之後的操作

public Object postProcessBeforeInitialization(Object arg0, String arg1);在bean初始化之前的操作

 第一個參數初始化的Bean第二個參數是Bean 執行個體的名稱

容器後處理器在容器執行個體化結束後,對容器進行額外的處理

必須實現BeanFactoryPostProcessor介面,

public void postProcessBeanFactory(ConfigurableListableBeanFactory arg0)

Spring撮提供了很多後視窗處理器如:

PropertyPlaceholderConfigurer:屬性預留位置配置器

PropertyOverrideConfigurer:另外一種屬性預留位置配置器

2種的區別在與後面一種具有覆蓋的性質

2.1、PropertyPlaceholderConfigurer

是spring內建PropertyEdito,它是beanFactoryPostProcess的實作類別

作用:讀取properties設定檔

通過該實作類別可以將spring的設定檔某些屬性值配置到properties檔案中,從而只要悠 properties的檔案,spring的設定檔即可進行相應變動。

使用1.PropertyPlaceholderConfigure修改某個部分的屬性時,不需要開啟Spring設定檔,從而保證不會將新的錯誤引入到spring的設定檔中。

優點:可以從主xml設定檔中分離出部分的配置資訊,

  可以支援多個設定檔,可以將設定檔 分割成多個設定檔,從而降低修改設定檔的風險,

 

2.2、PropertyOverrideConfigurer

會覆蓋掉XML檔案中的配置資訊,以.properties屬性檔案中的配置為主

如果沒有配置PropertyOverrideConfigurer則使用XML中的配置資訊

屬性格式:

beanName.property=value

其中beanName是springxml配置方便就近中的bean id屬性,value是屬性的值,對於多個properties檔案,通過locations屬性來進行指定

三、自訂屬性編輯器

應用情境:

類型無法識別,如日期等

實現

繼承PropertyEditorSupport

重寫setAsText()方法

package com.pb.entity;import java.util.Date;public class AppDate {    private Date date;    public Date getDate() {        return date;    }    public void setDate(Date date) {        this.date = date;    }        }

  自訂編輯器

package com.pb.entity;import java.beans.PropertyEditorSupport;import java.text.ParseException;import java.text.SimpleDateFormat;public class CustomerProperty extends PropertyEditorSupport {    private String format;    @Override    public void setAsText(String text) throws IllegalArgumentException {        SimpleDateFormat sdf=new SimpleDateFormat(format);        //super.setAsText(text);        try {            //轉換對象,能過setValue方法重新賦值            this.setValue(sdf.parse(text));        } catch (ParseException e) {            e.printStackTrace();        }    }    public String getFormat() {        return format;    }    public void setFormat(String format) {        this.format = format;    }        }

  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" xmlns:p="http://www.springframework.org/schema/p"    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">    <!--定義bean的類為自訂編輯器 -->    <bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">        <!-- 屬性 -->        <property name="customEditors">            <!-- map -->            <map>                <!-- key為日期 -->                <entry key="java.util.Date">                    <!--配置map的value -->                    <bean class="com.pb.entity.CustomerProperty">                        <!-- 配置屬性 -->                        <property name="format" value="yyyy-MM-dd"></property>                    </bean>                </entry>            </map>        </property>    </bean>    <!--配置AppDate的bean  --><bean id="appDate" class="com.pb.entity.AppDate"><property name="date"><value>2014-4-8</value></property></bean></beans>

  測試類別:

package com.pb.demo;import java.text.SimpleDateFormat;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import com.pb.entity.AppDate;public class Demo {    /**     * @param args     */    public static void main(String[] args) {        ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");        AppDate appDate=context.getBean("appDate",AppDate.class);        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");        System.out.println(sdf.format(appDate.getDate()));    }}

  

 

Spring(三)Bean繼續入門

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.