spring之Bean 的作用域、使用外部属性文件、表达式语言SpEL、Bean 的生命周期方法

1、Bean 的作用域

在 Spring 中, 可以在 元素的 scope 属性里设置 Bean 的作用域.

默认情况下, Spring 只为每个在 IOC 容器里声明的 Bean 创建唯一一个实例, 整个 IOC 容器范围内都能共享该实例:所有后续的 getBean() 调用和 Bean 引用都将返回这个唯一的 Bean 实例.该作用域被称为 singleton, 它是所有 Bean 的默认作用域

这里写图片描述

测试1:
这里写图片描述

Car.java

package com.zbiti.spring.beans.scope;

/**
 * Created by slb on 2018/5/14.
 */
public class Car {
    private  String brand;
    private  double price;

    public Car() {
        System.out.println("Car's Constructor...");
    }

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "Car{" +
                "brand='" + brand + '\'' +
                ", price=" + price +
                '}';
    }
}

beans-scope.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">

<!--scope值为prototype,创建容器对象之后调用getbean方法的时候调用Car的构造方法-->
  <bean id="car" class="com.zbiti.spring.beans.scope.Car" scope="prototype">
      <property name="brand" value="Audi"></property>
      <property name="price" value="300000"></property>
  </bean>
</beans>

scope指定单例还是多例。

Main.java

package com.zbiti.spring.beans.scope;

import com.zbiti.spring.beans.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * Created by slb on 2018/5/10.
 */
public class Main {
    public static  void main(String args[]){

        ApplicationContext ctx = new ClassPathXmlApplicationContext("beans-scope.xml");
        Car car1 = (Car) ctx.getBean("car");
        Car car2 = (Car) ctx.getBean("car");

        System.out.println(car1==car2);

    }
}

结果:
Car’s Constructor…
Car’s Constructor…
false
scope的值为prototype,容器对象每次调用getBean都会调用Car的构造方法。

=================================================================

测试2:
beans-scope.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">

<!--scope值为singleton,创建容器对象的时候调用Car的构造方法-->
  <bean id="car" class="com.zbiti.spring.beans.scope.Car" scope="singleton">
      <property name="brand" value="Audi"></property>
      <property name="price" value="300000"></property>
  </bean>
</beans>

Main.java

package com.zbiti.spring.beans.scope;

import com.zbiti.spring.beans.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * Created by slb on 2018/5/10.
 */
public class Main {
    public static  void main(String args[]){

        ApplicationContext ctx = new ClassPathXmlApplicationContext("beans-scope.xml");
       /* Car car1 = (Car) ctx.getBean("car");
        Car car2 = (Car) ctx.getBean("car");

        System.out.println(car1==car2);*/  //true

    }
}

结果:
Car’s Constructor…

====================================================================

2、使用外部属性文件

在配置文件里配置 Bean 时, 有时需要在 Bean 的配置里混入系统部署的细节信息(例如: 文件路径, 数据源配置信息等). 而这些部署细节实际上需要和 Bean 配置相分离

Spring 提供了一个 PropertyPlaceholderConfigurer 的 BeanFactory 后置处理器, 这个处理器允许用户将 Bean 配置的部分内容外移到属性文件中. 可以在 Bean 配置文件里使用形式为 ${var} 的变量, PropertyPlaceholderConfigurer 从属性文件里加载属性, 并使用这些属性来替换变量

Spring 还允许在属性文件中使用 ${propName},以实现属性之间的相互引用

测试1:

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


<!--加载数据源配置文件-->
    <context:property-placeholder location="classpath:db.properties" />
<!--
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="user" value="root"></property>
        <property name="password" value="root"></property>
        <property name="driverClass" value="com.mysql.cj.jdbc.Driver"></property>
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/ssm_crud1?useSSL=false"></property>

    </bean>-->

    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
        <property name="driverClass" value="${jdbc.driverClass}"></property>
        <property name="user" value="${jdbc.user}"></property>
        <property name="password" value="${jdbc.password}"></property>
    </bean>


</beans>

db.properties

jdbc.driverClass=com.mysql.jdbc.Driver
#数据库地址
jdbc.jdbcUrl=jdbc:mysql://localhost:3306/ssm_crud1?useUnicode=true&characterEncoding=utf8
#用户名
jdbc.user=root
#密码
jdbc.password=root
#最大连接数
c3p0.maxPoolSize=30
#最小连接数
c3p0.minPoolSize=10
#关闭连接后不自动commit
c3p0.autoCommitOnClose=false
#获取连接超时时间
c3p0.checkoutTimeout=10000
#当获取连接失败重试次数
c3p0.acquireRetryAttempts=21234567891011121314151617

Main.java

package com.zbiti.spring.beans.properties;


import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import javax.sql.DataSource;
import java.sql.SQLException;

/**
 * Created by slb on 2018/5/14.
 */
public class Main {
    public static  void main(String args[]) throws SQLException {

<!--加载容器配置文件-->
        ApplicationContext ctx = new ClassPathXmlApplicationContext("beans-properties.xml");
        DataSource dataSource = (DataSource) ctx.getBean("dataSource");
        System.out.println(dataSource.getConnection());
    }
}

结果:
com.mchange.v2.c3p0.impl.NewProxyConnection@3891771e

===============================================================

3、表达式语言SpEl

Spring 表达式语言(简称SpEL):是一个支持运行时查询和操作对象图的强大的表达式语言

语法类似于 EL:SpEL 使用 #{…} 作为定界符,所有在大框号中的字符都将被认为是 SpEL

SpEL 为 bean 的属性进行动态赋值提供了便利

通过 SpEL 可以实现
—通过 bean 的 id 对 bean 进行引用
—调用方法以及引用对象中的属性
—计算表达式的值
—正则表达式的匹配

字面量:
这里写图片描述

引用bean、 属性和方法
这里写图片描述
这里写图片描述

SpEL支持的运算符号
这里写图片描述
这里写图片描述

测试1:

beans-spel.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="address" class="com.zbiti.spring.beans.spel.Address">
        <property name="city" value="#{'BeiJing'}"></property>
        <property name="street" value="WuDaoKou"></property>
    </bean>

    <bean id="car" class="com.zbiti.spring.beans.spel.Car">
        <property name="brand" value="Audi"></property>
        <property name="price" value="50000"></property>
        <property name="tyrePerimeter" value="#{T(java.lang.Math).PI*80}"></property>
    </bean>


<!--引用其它bean的属性-->
    <bean id="person" class="com.zbiti.spring.beans.spel.Person">
        <property name="name" value="Tom"></property>
        <property name="car" value="#{car}"></property>
        <property name="city" value="#{address.city}"></property>
        <property name="info" value="#{car.price > 300000 ? '金领': '白领'}"></property>
    </bean>

</beans>

Address.java

package com.zbiti.spring.beans.spel;

/**
 * Created by slb on 2018/5/14.
 */
public class Address {
    private String city;
    private String street;

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getStreet() {
        return street;
    }

    public void setStreet(String street) {
        this.street = street;
    }

    @Override
    public String toString() {
        return "Address{" +
                "city='" + city + '\'' +
                ", street='" + street + '\'' +
                '}';
    }
}

Car.java

package com.zbiti.spring.beans.spel;

/**
 * Created by slb on 2018/5/14.
 */
public class Car {
    private  String brand;
    private double price;
    private  double tyrePerimeter;

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public double getTyrePerimeter() {
        return tyrePerimeter;
    }

    public void setTyrePerimeter(double tyrePerimeter) {
        this.tyrePerimeter = tyrePerimeter;
    }


    @Override
    public String toString() {
        return "Car{" +
                "brand='" + brand + '\'' +
                ", price=" + price +
                ", tyrePerimeter=" + tyrePerimeter +
                '}';
    }
}

Person.java

package com.zbiti.spring.beans.spel;

/**
 * Created by slb on 2018/5/14.
 */
public class Person {
    private String name;
    private Car car;
    private String city;

    private String info;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Car getCar() {
        return car;
    }

    public void setCar(Car car) {
        this.car = car;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getInfo() {
        return info;
    }

    public void setInfo(String info) {
        this.info = info;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", car=" + car +
                ", city='" + city + '\'' +
                ", info='" + info + '\'' +
                '}';
    }
}

Main.java

package com.zbiti.spring.beans.spel;


import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * Created by slb on 2018/5/14.
 */
public class Main {
    public static  void main(String args[]){
        ApplicationContext ctx = new ClassPathXmlApplicationContext("beans-spel.xml");
        Address address = (Address) ctx.getBean("address");

        System.out.println(address);


        System.out.println("=========================");

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

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

    }
}

结果:
这里写图片描述

====================================================================

4、Bean 的生命周期方法

Spring IOC 容器可以管理 Bean 的生命周期, Spring 允许在 Bean 生命周期的特定点执行定制的任务.

Spring IOC 容器对 Bean 的生命周期进行管理的过程
—通过构造器或工厂方法创建 Bean 实例
—为 Bean 的属性设置值和对其他 Bean 的引用
调用 Bean 的初始化方法
—Bean 可以使用了
当容器关闭时, 调用 Bean 的销毁方法

在 Bean 的声明里设置 init-method 和 destroy-method 属性, 为 Bean 指定初始化和销毁方法.

测试1:

MyBeanPostProcessor.java

package com.zbiti.spring.beans.cycle;

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

/**
 * Created by slb on 2018/5/14.
 */
public class MyBeanPostProcessor implements BeanPostProcessor {
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("postProcessBeforeInitialization:"+bean+", "+beanName);
        return bean;
    }

    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("postProcessAfterInitialization:"+bean+", "+beanName);
        Car  car = new Car();
        car.setBrand("Ford");
        return car;
    }
}

Car.java

package com.zbiti.spring.beans.cycle;

/**
 * Created by slb on 2018/5/14.
 */
public class Car {
    public Car(){
        System.out.println("Car's Constructor...");
    }

    private  String 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...");
    }

    @Override
    public String toString() {
        return "Car{" +
                "brand='" + brand + '\'' +
                '}';
    }
}

Main.java

package com.zbiti.spring.beans.cycle;


import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * Created by slb on 2018/5/14.
 */
public class Main {
    public static  void main(String args[]){
        ApplicationContext ctx = new ClassPathXmlApplicationContext("beans-cycle.xml");
        Car car = (Car) ctx.getBean("car");

        System.out.println(car);



    }
}

结果:
Car’s Constructor…
setBrand…
postProcessBeforeInitialization:Car{brand=’Audi’}, car
init…
postProcessAfterInitialization:Car{brand=’Audi’}, car
Car’s Constructor…
setBrand…
Car{brand=’Ford’}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring表达式语言SpEL)可以在Spring的XML配置文件、注解和代码中使用,常用于以下场景: 1. 在XML配置文件使用SpEL表达式来配置Bean的属性值。 例如,可以使用SpEL表达式来计算Bean的属性值,如下所示: ```xml <bean id="user" class="com.example.User"> <property name="name" value="#{systemProperties['user.name']}" /> </bean> ``` 上述配置中,使用SpEL表达式来获取系统属性“user.name”,并将其赋值给名为“user”的Bean的name属性。 2. 在注解中使用SpEL表达式来注入Bean的属性值。 例如,可以在@Value注解中使用SpEL表达式来注入属性值,如下所示: ```java @Component public class Example { @Value("#{systemProperties['user.name']}") private String userName; } ``` 上述代码中,在Example类中使用@Value注解和SpEL表达式来注入系统属性“user.name”的值到userName属性中。 3. 在代码中使用SpEL表达式来计算表达式的值。 例如,可以在代码中使用SpEL表达式来计算表达式的值,如下所示: ```java ExpressionParser parser = new SpelExpressionParser(); Expression expression = parser.parseExpression("'Hello, ' + #name"); String message = expression.getValue(new StandardEvaluationContext(), String.class, "World"); System.out.println(message); ``` 上述代码中,使用SpEL表达式来计算字符串“'Hello, ' + #name”的值,并将其赋值给message变量。在使用getValue方法时,可以传入EvaluationContext对象来提供表达式中用到的变量,也可以在getValue方法中直接传入变量的值,如上述代码中的“World”。这样,就可以在代码中动态地计算表达式的值。 总之,Spring表达式语言可以在很多场景中使用,可以帮助开发者方便地实现复杂的条件判断和动态计算。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值