一、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.springframework.beans.factory.support.DefaultListableBeanFactory@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.springframework.beans.factory.support.DefaultListableBeanFactory@3dc0bb: defining beans [hello]; root of factory hierarchy
得到的applicationContext对象:org.springframework.context.support.ClassPathXmlApplicationContext@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继续入门的更多相关文章

  1. Spring三 Bean的三种创建方式

    创建Bean的三种方式在大多数情况下,Spring容器直接通过new关键字调用构造器来创建Bean实例,而class属性指定Bean实例的实现类,但这不是实例化Bean的唯一方法.实际上,Spring ...

  2. 学习 Spring (三) Bean 的配置项 & 作用域

    Spring入门篇 学习笔记 配置项 Id: 整个 IoC 容器中的唯一标识 Class: 具体实例化的类(必须配置项) Scope: 作用域 Constructor arguments: 构造器参数 ...

  3. 一次性讲清楚spring中bean的生命周期之一:getSingleton方法

    要想讲清楚spring中bean的生命周期,真的是不容易,以AnnotationConfigApplicationContext上下文为基础来讲解bean的生命周期,AnnotationConfigA ...

  4. spring三种实例化bean的方式

    1构造函数实例化 2静态工厂方法实例化 3实例工厂方法实例化 service接口: package service; public interface PersonService { public v ...

  5. Spring(二)Bean入门

    一.BeanFactory介绍 1.1.Bean: 在Spring技术中是基于组件的 最基本了是最常用的单元 其实实例保存在Spring的容器当中 Bean通常被定义在配置文件当中,Bean实例化由S ...

  6. spring实例化bean三种方式

    我看了这篇博文<https://www.cnblogs.com/zhanglei93/p/6221546.html>,以及自己实践总结了关于spring实例化bean对象的3种方式. 一. ...

  7. spring创建bean的三种方式

    spring创建bean的三种方式: 1通过构造方法创建bean(最常用) 1.1 spring默认会通过无参构造方法来创建bean,如果xml文件是这样配置,则实体类中必须要有无参构造方法,无参构造 ...

  8. 【转】Spring学习---Bean配置的三种方式(XML、注解、Java类)介绍与对比

    [原文]https://www.toutiao.com/i6594205115605844493/ Spring学习Bean配置的三种方式(XML.注解.Java类)介绍与对比 本文将详细介绍Spri ...

  9. Spring实例化Bean三种方法:构造器、静态工厂、实例工厂

    Spring中Bean相当于java中的类,可以通过xml文件对bean进行配置和管理. 一.Bean的实例化: 构造器实例化.静态工厂实例化.实例工厂方式实例化. 目录: 构造器实例化: xml配置 ...

随机推荐

  1. 封装Js事件代理方法

    // 封装事件代理 function delegateEvent(element, tag, event, listener) { // 判断是否支持addEventlistener if(eleme ...

  2. ADT-bundle(Android Development Tools)环境配置

    Android开发环境有两套比较主流的:ADT-bundle和Android Studio,前者是Eclipse插件的形式进行开发,后者是Android的官方IDE. ADT环境的配置与调试:(1)安 ...

  3. Tips9: Destroy( )函数中的 延迟摧毁 功能

    你知道Object.Destroy()函数吗?在脚本中用来摧毁一个游戏物体或组件,可是你知道他能在执行后延迟一段时间后才摧毁物体吗,其实很简单: using UnityEngine; public c ...

  4. uboot命令及内核启动参数

        修改:mw [内存地址] [值] [长度] 例如:mw 0x02000000 0 128 表示修改地址为0x02000000~0x02000000+128的内存值为0. 显示:md [内存地址 ...

  5. Origami – 用于 Quartz 的免费的交互设计框架

    Origami 是一个为 Quartz Composer 开发的免费的工具包——由Facebook设计团队创建,让交互设计原型更加简单,不需要编程. 如今,大多数设计师通过创建静态原型来表达要实现的应 ...

  6. IT168关于敏捷开发采访

    1.我们知道敏捷开发是一套流程和方法的持续改进,通过快速迭代的方式交付产品,从而控制和降低成本.但是在实行敏捷初期,往往看不到很好的效果.这里面,您觉得问题主要出在哪?团队应如何去解决问题?金根:我认 ...

  7. CSS布局 -- 左右定宽,中间自适应

    左右定宽,中间自适应 有几种方法可以实现 改变窗口大小看看? 方案一: 左右设置绝对定位,定宽,中间设置margin-left  margin-right 查看 demo <!DOCTYPE h ...

  8. .net C# 对虚拟目录IIS的操作

    一.查看虚拟目录是否存在 private bool IsExitesVirtualDir(string virtualdirname) {    bool exited =false;    Dire ...

  9. C#实现的18位身份证格式验证算法

    18位身份证标准在国家质量技术监督局于1999年7月1日实施的GB11643-1999<公民身份号码>中做了明确的规定. GB11643-1999<公民身份号码>为GB1164 ...

  10. JS获取屏幕高度

    主要使用了document对象关于窗口的一些属性,这些属性的主要功能和用法如下. 要 得到窗口的尺寸,对于不同的浏览器,需要使用不同的属性和方法:若要检测窗口的真实尺寸,在netscape下需要使用w ...