Spring4深入理解IOC&DI03----Bean配置--SpEL,IOC 容器中 Bean 的生命周期

参考代码下载github:https://github.com/changwensir/java-ee/tree/master/spring4

一、SpEL

  --• Spring 表达式 语言 (简称 SpEL ):是 一个 支持运行时查询和操作对象图的强大的表达式语言
  --• 语法类似于 EL SpEL 使用 # {…} 作为定界符,所有在大框号中的字符都将被认为是 SpEL
  --• SpEL bean 的属性进行动态赋值提供了便利
  --• 通过 SpEL 可以实现:
    – 通过 bean id bean 进行 引用
    – 调用 方法以及引用对象中的属性
    – 计算 表达式的值
    – 正则表达式 匹配
1).SpEL:字面量
字面 量的 表示:
整数: < propertyname="count" value=" #{5 } "/>
小数: < propertyname="frequency" value=" #{89.7 } "/>
科学计数 法: < propertyname="capacity" value=" #{1e4 } "/>
String 可以使用单引号或者双引号作为字符串的定界符 < propertyname =“name” value = " #{'Chuck'} "/> <property name='name'value=' #{"Chuck "} '/>
Boolean <property name="enabled"value=" #{false} "/>
2).引用 Bean、属性和方法


3).SpEL支持的运算符号



创建PersonSpEL类,其它的类自行创建

public class PersonSpEL {
    private Car car;
    private String name;

    //根据car的price确定Info
    private String info;
    //引用address bean的city的属性
    private String city;

//省去get,set方法
}

<?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="address" class="Spring4_IOC.bean.Address">
              <!-- 使用spel为属性赋一个字面值(也就是Int,String..)-->
              <property name="city" value="#{'beiJing'}"/>
              <property name="street" value="#{'WuDaoKou'}"/>
       </bean>

       <bean id="car" class="Spring4_IOC.bean.Car">
              <property name="brand" value="Auti"/>
              <property name="price" value="500000"/>
              <!-- 使用SpEL 引用类的静态属性-->
              <property name="maxSpeed" value="#{T(java.lang.Math).PI * 80}"/>
       </bean>

       <bean id="person" class="Spring4_IOC.bean.PersonSpEL">
              <!-- 使用SpEL来应用其它的Bean,也可以用ref-->
              <property name="car" value="#{car}"/>
              <!-- 使用SpEL来应用其它的Bean 的属性-->
              <property name="city" value="#{address.city}"/>
              <!-- 在SpEL 中使用运算符-->
              <property name="info" value="#{car.price > 30000 ? '金领' : '白领'}"/>
              <property name="name" value="Tom"/>
       </bean>
</beans>
    @Test
    public void testSpEL() {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("Spring4_IOC/beans-spel.xml");
        Address address = (Address) ctx.getBean("address");
        System.out.println(address);

        Car car1 = (Car) ctx.getBean("car");
        System.out.println(car1);

        PersonSpEL person = (PersonSpEL) ctx.getBean("person");
        System.out.println(person);
    }

二、IOC 容器中 Bean 的生命周期方法

  --• Spring IOC 容器可以管理 Bean 的生命周期 ,Spring 允许在 Bean 生命周期的特定点执行定制的任务 .
  --• Spring IOC 容器对 Bean 的生命周期进行管理的过程 :
    – 通过构造器或工厂方法创建 Bean 实例
    – Bean 的属性设置值和对其他 Bean 的引用
    – 调用 Bean 的初始化方法
    – Bean 可以使用了
    – 当容器关闭时 , 调用 Bean 的销毁 方法
  --• Bean 的声明里设置 init -method destroy-method 属性 , Bean 指定初始化和销毁方法 .
public class CarCycle {
    private String brand;

    public CarCycle() {
        System.out.println("CarCycle's constructor...");
    }

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        System.out.println("setBrand...");
        this.brand = brand;
    }

    public void init() {
        System.out.println("init...");
    }

    public void destroy() {
        System.out.println("destroy...");
    }
//省去toString方法
}
<?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 http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">

    <bean id="car" class="Spring4_IOC.bean.CarCycle"
            init-method="init" destroy-method="destroy">
        <property name="brand" value="Audi"/>
    </bean>
</beans>
    @Test
    public void testCycle() {
        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("Spring4_IOC/beans-cycle.xml");
        CarCycle car = (CarCycle) ctx.getBean("car");
        System.out.println("---->"+car);

        //关闭IOC容器
        ctx.close();
    }
CarCycle's constructor...
setBrand...
init...
---->CarCycle{brand='Audi'}
destroy...

1-2.Bean后置处理器

  • Bean 后置处理器允许在调用初始化方法前后对 Bean 进行额外的处理 .
  • Bean 后置处理器对 IOC 容器里的所有 Bean 实例逐一处理 , 而非单一实例 . 其典型应用是 : 检查 Bean 属性的正确性或根据特定的标准更改 Bean 的属性 .
  • Bean 后置处理器而言 , 需要实现 interface.BeanPostProcessor接口 . 在初始化方法被调用前后 ,Spring 将把每个 Bean 实例分别传递给上述接口的以下两个方法 :

/**
 * MyBeanPostProcessor
 * Bean 后置处理器允许在调用初始化方法前后对 Bean 进行额外的处理.
 * Bean 后置处理器对 IOC 容器里的所有 Bean 实例逐一处理, 而非单一实例.
 * 其典型应用是: 检查 Bean 属性的正确性或根据特定的标准更改 Bean 的属性.
 */
public class MyBeanPostProcessor implements BeanPostProcessor {
    public Object postProcessBeforeInitialization(Object o, String s) throws BeansException {
        System.out.println("postProcessBeforeInitialization..." + o+","+s);
        //过滤
        if ("car".equals(o)){
        }
        return o;
    }

    public Object postProcessAfterInitialization(Object o, String s) throws BeansException {
        System.out.println("postProcessAfterInitialization..." + o+","+s);
        CarCycle car = new CarCycle();
        car.setBrand("Ford");
        return car;
    }
}
在beans-cycle里增加如下内容
    <!--实现BeanPostProcessor接口,并具体提供两个方法的编写
    postProcessBeforeInitialization(Object bean, String beanName): init-method之前被调用
     postProcessAfterInitialization(Object bean, String beanName): init-method之后被调用

     bean: bean实例本身
     beanName: IOC容器配置的bean的名字
     返回值:是实际上返回给用户的那个bean,可以在以上两个方法中修改返回的bean,甚至返回一个新的bean
     -->
    <!--配置bean的后置处理器: 不需要配置id, IOC容器自动识别是一个BeanPostProcessor-->
    <bean class="Spring4_IOC.cycle.MyBeanPostProcessor"/>
测试方法同上,结果如下:
CarCycle's constructor...
setBrand...
postProcessBeforeInitialization...CarCycle{brand='Audi'},car
init...
postProcessAfterInitialization...CarCycle{brand='Audi'},car
CarCycle's constructor...
setBrand...
---->CarCycle{brand='Ford'}
destroy...



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值