spring知识三-----SpEL&生命周期&bean配置方式

    xiaoxiao2021-03-25  38

    SpEL—–熟悉

    SpEL概述

    spring的表达式语言。用在配置文件中,是一个支持运行时查询和操作对象图的强大的表达式语言。他的语法类似于EL表达式。SpEL使用 #{ } 作为定界符,所有在大框号中的字符都将被认为是 SpEL。SpEL 为 bean 的属性进行动态赋值提供了便利。

    SpEL可以实现的功能:

    1、通过 bean 的 id 对 bean 进行引用 2、引用对象中的属性以及调用方法 3、计算表达式的值 4、正则表达式的匹配

    <!-- 为字面赋值 --> <bean id="address" class="com.wf.springspel.Address"> <property name="city" value="#{'henan'}"></property> <property name="street" value="luoyang"></property> </bean> <!-- 引用类的静态属性 --> <bean id="car" class="com.wf.springspel.Car"> <property name="brand" value="Audi"></property> <property name="price" value="1000000"></property> <property name="carlength" value="#{T(java.lang.Math).PI*8 }"></property> </bean> <bean id="user" class="com.wf.springspel.User"> <property name="name" value="tom"></property> <!-- 引用其他bean对象 --> <property name="car" value="#{car}"></property> <!-- <property name="car" ref="car"></property> --> <!-- 引用其他bean对象的属性 --> <property name="city" value="#{address.city}"></property> <!-- el表达式进行选择 --> <property name="info" value="#{car.price>30000?'老板':'员工'}"></property> </bean>

    SpEL 语法

    SpEL:字面量

    字面量的表示: 整数:<property name="count" value="#{5}"/> 小数:<property name="frequency" value="#{89.7}"/> 科学计数法:<property name="capacity" value="#{1e4}"/> String可以使用单引号或者双引号作为字符串的定界符号: <property name=“name” value="#{'Chuck'}"/> 或 <property name='name' value='#{"Chuck"}'/> Boolean:<property name="enabled" value="#{false}"/>

    引用 Bean、属性和方法

    <!--引用其他对象:通过value属性和SpEL 配置Bean之间的应用关系 --> <property name="car" value="#{car}"></property> <!--引用其他对象的属性--> <property name="city" value="#{address.city}"></property> <!--调用其他方法,记得括号--> <property name="city" value="#{address.toString()}"></property> <!--链式调用其他方法,记得括号--> <property name="city" value="#{address.toString().toUpperCase()}"></property>

    运算符的操作

    <!--算数运算符的操作 【+、-、*、/、%、^】 --> <property name="add" value="#{account.count+125}"></property> <property name="remainder" value="#{account.total % account.count}"></property> <!--加号作为连接符--> <construtor-arg name="name" value="#{performer.fisrtName+':'+performer.lasrName}" /> <!--比较运算符 <、>、==、<=、>=、lt、gt、eq、le、ge --> <property name="equal" value="#{account.count == 125}"></property> <property name="hasCapacity" value="#{account.count le 125}"></property> <!--逻辑运算符 and、or、not--> <property name="largeCircle" value="#{shape.kind == 'circle' and shape.perimeter gt 1000}"></property> <!--if else 运算符 --> <property name="info" value="#{car.price>30000?'老板':'员工'}"></property> <!--正则表达式 matches --> <construtor-arg name="email" value="#{admin.email matches '[a-z0-9]' " />

    静态方法或静态属性操作

    <!--调用静态方法或静态属性,通过 T() 调用一个类的静态方法,它将返回一个 Class Object,然后再调用相应的方法或属性--> <property name="carlength" value="#{T(java.lang.Math).PI*8 }"></property>

    Bean生命周期—–了解

    简单的生命周期过程

    类似于Servlet,spring也可以进行生命周期管理。 Spring IOC 容器可以管理 Bean 的生命周期, Spring 允许在 Bean 生命周期的特定点执行定制的任务。 Spring IOC 容器对 Bean 的生命周期进行管理的过程: 1、通过构造器或工厂方法创建 Bean 实例(构造器调用); 2、为 Bean 的属性设置值和对其他 Bean 的引用(setter方法调用); 3、调用 Bean 的初始化方法; 4、Bean 的使用; 5、当容器关闭时, 调用 Bean 的销毁方法; 注意:在 Bean 的声明里设置 init-method 和 destroy-method 属性, 为 Bean 指定初始化和销毁方法。 注意:ApplicationContext没有提供close方法,我们可以利用他的实现类进行来关闭。 【ClassPathXmlApplicationContext cxt = new ClassPathXmlApplicationContext(“beans-cycle.xml”);】

    // 类 public class Car { private String brand; public String getBrand() { return brand; } public void setBrand(String brand) { System.out.println("setter value....."); this.brand = brand; } public Car() { System.out.println("Car constructors...... "); } public void init(){ // 名称不固定init2也是可以 System.out.println("Car init....."); } public void destory(){ System.out.println("car destory......"); } @Override public String toString() { return "Car [brand=" + brand + "]"; } } // 配置 <!-- 先调用构造器,然后setter方法,然后init方法,然后destory --> <bean id="car" class="com.wf.springcycle.Car" init-method="init" destroy-method="destory"> <property name="brand" value="Auto"></property> </bean>

    创建 Bean 后置处理器的生命周期过程

    Bean 后置处理器允许在调用初始化方法前后对 Bean 进行额外的处理。 Bean 后置处理器对 IOC 容器里的所有 Bean 实例逐一处理, 而非单一实例。 其典型应用是: 检查 Bean 属性的正确性或根据特定的标准更改 Bean 的属性. 对Bean 后置处理器应用,需要实现【BeanPostProcessor 】接口,在初始化方法被调用前后, Spring 将把每个 Bean 实例分别传递给上述接口的以下两个方法【postProcessAfterInitialization】和【postProcessBeforeInitialization】中。 Spring IOC 容器对 Bean 的生命周期进行管理的过程: 1、通过构造器或工厂方法创建 Bean 实例; 2、为 Bean 的属性设置值和对其他 Bean 的引用; 3、将 Bean 实例传递给 Bean 后置处理器的 postProcessBeforeInitialization 方法; 4、调用 Bean 的初始化方法; 5、将 Bean 实例传递给 Bean 后置处理器的 postProcessAfterInitialization方法; 6、Bean 的使用; 7、当容器关闭时, 调用 Bean 的销毁方法;

    public class MyBeanPostProcessor implements BeanPostProcessor { @Override //bean代表容器创建的实例,beanName代表bean的id public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("后置处理器postProcessAfterInitialization"+bean+"..."+beanName); if("car".equals(beanName)){ System.out.println("car is changing"); Car car = (Car) bean; car.setBrand("DaBen"); } return bean; } @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("前置处理器postProcessAfterInitialization"+bean+"..."+beanName); return bean; } } // 配置 <!-- 后置处理器的配置不需要Id,spring容器会根据BeanPostProcessor接口进行自动识别 后置处理器类需要实现BeanPostProcessor,然后重写 postProcessAfterInitialization(Object bean, String beanName) Init之前 postProcessBeforeInitialization(Object bean, String beanName) Init之后 方法。 bean代表容器创建的实例,beanName代表bean的id ,可以在这两个方法进行一些条件判断, 过滤出要进行修改的bean实例。 --> <bean class="com.wf.springcycle.MyBeanPostProcessor"> </bean>

    Bean的配置方式——熟悉

    通过全类名进行反射配置—掌握

    我们对于bean的配置一般都是利用全类名进行反射。【常用的,最基本的】

    通过工厂方法—熟悉

    【静态工厂方法&实例工厂方法,我们需要额外的创建一个工厂类】

    静态工厂方法 调用静态工厂方法创建 Bean是将对象创建的过程封装到静态方法中. 当客户端需要对象时, 只需要简单地调用静态方法, 而不同关心创建对象的细节,要声明通过静态方法创建的 Bean, 需要在 Bean 的 class 属性里指定拥有该工厂的方法的类, 同时在 factory-method 属性里指定工厂方法的名称. 最后, 使用 【constrctor-arg】元素为该方法传递方法参数。

    //创建工厂类 /*静态工厂方法:通过调用静态的工厂方法,进行初始化bean*/ public class CarStaticFactory { static Map<String, Car> cars=new HashMap<String, Car>(); // 谨记在声明集合时,进行初始化。。 static{ cars.put("Audi", new Car("Audi", 30000)); cars.put("DaZh", new Car("DaZh", 30000)); cars.put("XianDai", new Car("XianDai", 30000)); } //封装到静态方法中获取对象 public static Car getCar(String name){ return cars.get(name); } } //配置 <!-- 通过静态工厂方法进行配置bean, class属性:指向静态工厂的类名, factory-method属性:指向静态工厂方法, constructor-arg属性 : 指向要传递的参数, --> <bean id="car01" class="com.wf.springfactory.CarStaticFactory" factory-method="getCar"> <constructor-arg name="name" value="Audi"></constructor-arg> </bean>

    实例工厂方法 实例工厂方法: 将对象的创建过程封装到另外一个对象实例的方法里. 当客户端需要请求对象时, 只需要简单的调用该实例方法而不需要关心对象的创建细节. 要声明通过实例工厂方法创建的 Bean,需要在 bean 的 factory-bean 属性里指定拥有该工厂方法的 Bean,在 factory-method 属性里指定该工厂方法的名称,使用 construtor-arg 元素为工厂方法传递方法参数。

    /*实例工厂方法:通过创建实例工厂,然后调用工厂的实例方法,进行初始化bean*/ public class CarInstanceFactory { static Map<String, Car> cars=new HashMap<String, Car>(); public Car getCar(String name){ return cars.get(name); } public CarInstanceFactory() { cars.put("Audi", new Car("Audi", 30000)); cars.put("DaZh", new Car("DaZh", 30000)); cars.put("XianDai", new Car("XianDai", 30000)); } } <!-- 通过工厂的实例配置bean 首先设定 CarInstanceFactory 实例工厂 bean --> <bean id="CarInstanceFactory" class="com.wf.springfactory.CarInstanceFactory" > </bean> <!-- factory-bean属性:指向实例工厂的bean, factory-method属性:指向实例工厂方法, constructor-arg属性 : 指向要传递的参数, --> <bean id="car02" factory-bean="CarInstanceFactory" factory-method="getCar"> <constructor-arg value="Audi"> </constructor-arg> </bean>

    FactoryBean —掌握

    【整合其余框架会利用, quartz】需要自定义 FactoryBean。 Spring 中有两种类型的 Bean, 一种是普通Bean, 另一种是工厂Bean, 即FactoryBean。 工厂 Bean 跟普通Bean不同, 其返回的对象不是指定类的一个实例, 其返回的是该工厂 Bean 的 getObject 方法所返回的对象 。

    在利用FactoryBean配置时,我们需要实现Spring给我们提供的FactoyBean接口。,并且重写其中的方法。

    //自定义FactoryBean需要实现spring提供的FactoryBean接口 // 如果设置有属性,可以通过配置文件的property属性进行赋值 // 整合quartz需要使用 public class CarFactoryBean implements FactoryBean<Car> { @Override // 返回 bean 对象 public Car getObject() throws Exception { // TODO Auto-generated method stub return new Car("BMW", 200000) ; } @Override // 返回bean的类型 public Class<?> getObjectType() { // TODO Auto-generated method stub return Car.class; } @Override // 是否是单例 public boolean isSingleton() { // TODO Auto-generated method stub return true; } } <!-- 通过FactoryBean 进行配置bean class:指向自定义的FactoryBean全类名 property :配置自定义的factoryBean的属性 实际返回的实例是FactoryBean 的getObject()方法返回的实例, --> <bean id="car03" class="com.wf.springfactory.CarFactoryBean"> </bean>

    源码可以在我的资源中查看 或者 github地址 https://github.com/wangfa1994/SpringLearning/tree/spring003

    转载请注明原文地址: https://ju.6miu.com/read-50374.html

    最新回复(0)