标签:import 3.5 instant close 作用域 国际化 nfa system map
我们前边的demo中用到的spring 工厂类是ClassPathXmlApplicationContext,从上图可以看到他还有一个兄弟类FileSystemApplicationContext,这个类是加载非classpath路径下的配置文件,本质是一样的。
从继承关系图中可以看到我们经常看到的ApplicationContext,这个是新版本才引入的工厂类接口。在旧版本中是BeanFactory,是在旧版本的基础上增加了几个新功能,如国际化,resourceLoader等。还有一个区别就是加载bean的时机的区别,Beanfactory是在使用bean的时候创建的;ApplicationContext是在加载配置文件的时候就将所有非懒加载的单例创建出来了。
@Test
/**
* 使用beanFactory加载bean
*/
public void demo3() {
// 老方式的工厂类,需要自己创建Resource对象进行加载。
BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("application-context.xml"));
// 通过工厂获取类对象
UserService userService = (UserService) beanFactory.getBean("userService");
userService.sayHello();
}
一般情况都是用第一种方式,只有类的构造非常复杂的情况下才会用后边的俩种。
package com.ioc.demo2;
/**
* Bean实例化的三种方式:采用无参的构造方法的方式
*/
public class Bean1 {
public Bean1() {
System.out.println("Bean1 被实例化了。");
}
}
<!-- 无参数构造方法构建 -->
<bean id="bean1" class="com.ioc.demo2.Bean1"></bean>
@Test
public void demo1() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("application-context.xml");
Bean1 bean = (Bean1) applicationContext.getBean("bean1");
}
/**
* Bean的实例化三种方式:静态工厂实例化方式
*/
public class Bean2 {
}
/**
* Bean2的静态工厂
*/
public class Bean2Factory {
public static Bean2 createBean2() {
System.out.println("Bean2Factory 执行了。");
return new Bean2();
}
}
<!-- 静态工厂的方式 -->
<bean id="bean2" class="com.ioc.demo2.Bean2Factory" factory-method="createBean2"></bean>
@Test
public void demo2() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("application-context.xml");
Bean2 bean = (Bean2) applicationContext.getBean("bean2");
}
/**
* 使用实例工厂模式实例化
*/
public class Bean3 {
}
/**
* Bean3的实例工厂
*/
public class Bean3Factory {
public Bean3 createBean3() {
System.out.println("Bean3Factory 被调用了。");
return new Bean3();
}
}
<!-- 实例工厂的方式 -->
<bean id="bean3Factory" class="com.ioc.demo2.Bean3Factory"></bean>
<bean id="bean3" factory-bean="bean3Factory" factory-method="createBean3"></bean>
@Test
public void demo3() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("application-context.xml");
Bean3 bean = (Bean3) applicationContext.getBean("bean3");
}
类别 | 说明 |
---|---|
singleton(默认) | 在SpringIOC容器中仅存在一个Bean实例,Bean以单实例的方式存在 |
prototype | 每次调用getBean()时都会返回一个新的实例 |
request | 每个HTTP请求都会创建一个新的Bean,该作用域仅适用于WebApplicationContext环境 |
session | 同一个HTTP session共享一个Bean,不同的HTTP session使用不同的Bean。该作用域仅适用于WebApplicationContext环境 |
spring初始化bean或销毁bean时,有时候需要做一些处理工作,因此spring可以在创建和销毁bean的时候调用bean的声明周期方法。
<bean id="xxx" class="...Yoo" init-method="init" destory-method="destory" />
当bean在被载入到容器中时会调用init;当bean从容器中删除的时候调用destroy(scope=singleton有效)
即调用类的构造方法。
即调用类的属性设置方法。
即为该bean设置name的时候调用,可以想象为容器为map,name就是那个key。
即为该bean设置容器的时候调用。
即在调用init-method之前调用。
属性设置后调用。
<bean init-method="init">
指定的初始化方法执行init方法。
即在调用init-method之后调用。
即调用bean中的业务方法。
spring自身中的销毁方法。
<bean destory-method="teardown">
指定的销毁方法执行teardown方法。
package com.ioc.demo3;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
public class Bean implements BeanNameAware, ApplicationContextAware, InitializingBean, DisposableBean{
private String name;
public Bean() {
System.out.println("第一步:构造方法");
}
public void setName(String name) {
System.out.println("第二步:设置属性");
this.name = name;
}
public void setBeanName(String name) {
System.out.println("第三步:设置bean的名称:" + name);
}
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("第四步:设置bean工厂");
}
public void afterPropertiesSet() throws Exception {
System.out.println("第六步:属性设置后");
}
public void init() {
System.out.println("第七步:初始化方法");
}
public void run() {
System.out.println("第九步:业务代码");
}
public void destroy() throws Exception {
System.out.println("第十步:spring自身的销毁");
}
public void teardown() {
System.out.println("第十一步:销毁方法");
}
}
package com.ioc.demo3;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
public class MyBeanPostProcessor implements BeanPostProcessor {
// 可以用beanName对要生效的bean做过滤操作
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("第四步:bean初始化前");
return bean;
}
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("第八步:bean初始化后方法");
return bean;
}
}
<!-- Bean的声明周期============================================ -->
<bean id="bean" class="com.ioc.demo3.Bean" init-method="init" destroy-method="teardown">
<property name="name" value="xxx"></property>
</bean>
<!-- 注意这个配置是对所有的bean都生效的 -->
<bean class="com.ioc.demo3.MyBeanPostProcessor"></bean>
package com.ioc.demo3;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringDemo3 {
@Test
public void demo1() {
// ApplicationContext接口没有close方法,故直接使用了其实现类
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("application-context.xml");
Bean bean = (Bean)context.getBean("bean");
bean.run();
context.close();
}
}
第一步:构造方法
第二步:设置属性
第三步:设置bean的名称:bean
第四步:设置bean工厂
第四步:bean初始化前
第六步:属性设置后
第七步:初始化方法
第八步:bean初始化后方法
第九步:业务代码
第十步:spring自身的销毁
第十一步:销毁方法
这个本质上是可以对类中的方法做动态代理,为后边的AOP做铺垫。
下边举个栗子:在delete方法前面加一个鉴权的功能,不更改具体的类方法。
package com.ioc.demo3;
public interface BeanDao {
public void find();
public void add();
public void delete();
public void update();
}
package com.ioc.demo3;
public class BeanDaoImpl implements BeanDao {
public void find() {
System.out.println("查询");
}
public void add() {
System.out.println("添加");
}
public void delete() {
System.out.println("删除");
}
public void update() {
System.out.println("更新");
}
}
package com.ioc.demo3;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
public class MyBeanPostProcessor implements BeanPostProcessor {
public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
System.out.println("第四步:bean初始化前");
return bean;
}
public Object postProcessAfterInitialization(final Object bean, String beanName) throws BeansException {
System.out.println("第八步:bean初始化后方法");
if (beanName.equals("beanDao")) {
Object proxy = Proxy.newProxyInstance(bean.getClass().getClassLoader(), bean.getClass().getInterfaces(), new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.getName().equals("delete")) {
System.out.println("鉴权是否是root用户");
return method.invoke(bean, args);
}
return method.invoke(bean, args);
}
});
return proxy;
}
return bean;
}
}
<bean class="com.ioc.demo3.MyBeanPostProcessor"></bean>
<bean id="beanDao" class="com.ioc.demo3.BeanDaoImpl"></bean>
package com.ioc.demo3;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringDemo3 {
@Test
public void demo1() {
ApplicationContext context = new ClassPathXmlApplicationContext("application-context.xml");
BeanDao beanDao = (BeanDao)context.getBean("beanDao");
beanDao.add();
beanDao.delete();
beanDao.find();
beanDao.update();
}
}
【一步一步学习spring】spring bean管理(上)
标签:import 3.5 instant close 作用域 国际化 nfa system map
原文地址:https://www.cnblogs.com/xxxuwentao/p/9587969.html