1、ApplicationContextAware:在Bean初始化过程中initializeBean()函数中
2、InitializingBean:在Bean初始化过程中initializeBean()函数中
3、LifeCycle:在bean初始化完成后finishRefresh中执行;
4、ApplicationListener:在bean初始化完成后finishRefresh中执行;
5、CommandLineRunner:在所有bean都初始化完成后调用,在AfterFinish中执行
6、ApplicationRunner:在所有bean都初始化完成后调用,在AfterFinish中执行
@Component
public class StartupListener implements ApplicationContextAware, ServletContextAware,
InitializingBean, ApplicationListener<ContextRefreshedEvent> {
protected Logger logger = LogManager.getLogger();
@Override
public void setApplicationContext(ApplicationContext ctx) throws BeansException {
logger.info("1 => StartupListener.setApplicationContext");
}
@Override
public void setServletContext(ServletContext context) {
logger.info("2 => StartupListener.setServletContext");
}
@Override
public void afterPropertiesSet() throws Exception {
logger.info("3 => StartupListener.afterPropertiesSet");
}
@Override
public void onApplicationEvent(ContextRefreshedEvent evt) {
logger.info("4.1 => MyApplicationListener.onApplicationEvent");
if (evt.getApplicationContext().getParent() == null) {
logger.info("4.2 => MyApplicationListener.onApplicationEvent");
}
}
}
View Code
运行时,输出的顺序如下:
1 => StartupListener.setApplicationContext
2 => StartupListener.setServletContext
3 => StartupListener.afterPropertiesSet
4.1 => MyApplicationListener.onApplicationEvent
4.2 => MyApplicationListener.onApplicationEvent
4.1 => MyApplicationListener.onApplicationEvent
BeanFactoryAware
要直接在自己的代码中读取spring的bean,我们除了根据常用的set外,也可以通过spring的BeanFactoryAware接口实现,只要实现setBeanFactory方法就可以。
private BeanFactory beanFactory;
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
这样我们就可以直接拿东西用了,如
Object object = beanFactory.getBean(beanName);
我们既然可以通过set来拿到我们要的对象,为什么还要用这个beanFactory呢,道理很简单,因为有些情况是需要动态的去获取对象的,比如说我有10个银行的处理对象,他们都继承了我的BankService对象,但是具体处理的时候要哪家银行的对象呢?这个依赖于用户的选择。你可以注入10个BankService实例,然后用if --else来搞,不过那样太坨了。每增加一家银行你都需要改代码。
通过beanFactory的话,那就一行代码搞定,只要给beanName就OK了,动点脑筋吧beanName配置的有规律点,然后根据用户的银行选择,凑出个beanName,大功告成了!
简单一句话的理解是:beanFactory让你可以不依赖注入方式,随意的读取IOC容器里面的对象,不过beanFactory本身还是要注入的,呵呵
ApplicationContextAware
当一个类实现了这个接口(ApplicationContextAware)之后,这个类就可以方便获得ApplicationContext中的所有bean。换句话说,就是这个类可以直接获取spring配置文件中,所有有引用到的bean对象。
public class LocalUtil implements ApplicationContextAware{
private static ApplicationContext applicationcontext;
@Override
public void setApplicationContext(ApplicationContext applicationcontext)throws BeansException {
this.applicationcontext = applicationcontext;
}
public static ApplicationContext getApplicationContext()throws BeansException {
return applicationcontext;
}
}
ResourceLoaderAware
ResourceLoaderAware回调接口负责将ResourceLoader对象注入到当前的受管Bean实例中,其定义如下。当受管Bean获得ResourceLoader对象后,它便能够通过它获得各种资源。
public interface ResourceLoaderAware {
void setResourceLoader(ResourceLoader resourceLoader);
}
BeanNameAware
如果某个bean需要访问配置文件中本身bean的id属性,这个Bean类通过实现该接口,在依赖关系确定之后,初始化方法之前,提供回调自身的能力,从而获得本身bean的id属性,该接口提供了void setBeanName(String name)方法实现,需要指出的是该方法的name参数就是该bean的id属性,加调该setBeanName方法可以让bean获取得自身的id属性。
ServletContextAware
在spring中,凡是实现ServletContextAware接口的类,都可以取得ServletContext。
BeanPostProcess
BeanPostProcessor接口中的两个方法,如下:
public interface BeanPostProcessor {
//Bean初始化的前置处理器
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
//Bean初始化的后置处理器
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}
应用中自定义的Bean,可以实现这个接口,并覆盖这两个方法来控制Bean的初始化过程,即在Bean的初始化之前做一件事,即调用postProcessBeforeInitialization方法,也可以在Bean的初始化之后做一件事,即调用postProcessAfterInitialization方法。
BeanClassLoaderAware
允许一个获取它的classLoader(即当前bean factory加载bean类使用的class loader)的回调类,实现了void setBeanClassLoader(ClassLoader classLoader);
InitializingBean
接口为bean提供了初始化方法的方式,它只包括afterPropertiesSet方法,凡是继承该接口的类,在初始化bean的时候会执行该方法。
PropertyPlaceholderConfigurer
是个bean工厂后置处理器的实现,也就是 BeanFactoryPostProcessor接口的一个实现。PropertyPlaceholderConfigurer可以将上下文(配置文 件)中的属性值放在另一个单独的标准java Properties文件中去。在XML文件中用${key}替换指定的properties文件中的值。这样的话,只需要对properties文件进 行修改,而不用对xml配置文件进行修改。
<bean id="propertyConfigurer"class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath: conf/sqlmap/jdbc.properties </value>
</list>
</property>
</bean>
<bean id="dataSource"class="org.apache.commons.dbcp.BasicDataSource"destroy-method="close">
<property name="driverClassName"value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}"/>
<property name="password"value="${jdbc.password}" />
</bean>
package com.slp.util;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
public class CustomizedPropertyConfigurer extends PropertyPlaceholderConfigurer {
private static Map<String,String> ctxPropMap;
@Override
protected void processProperties(ConfigurableListableBeanFactory beanFactoryToProcess, Properties props) throws BeansException {
super.processProperties(beanFactoryToProcess, props);
ctxPropMap = new HashMap<>();
for (Object key : props.keySet()){
String keyStr = key.toString();
String value = String.valueOf(props.get(keyStr));
ctxPropMap.put(keyStr,value);
}
}
public static String getCtxProp(String name) {
return ctxPropMap.get(name);
}
public static Map<String, String> getCtxPropMap() {
return ctxPropMap;
}
}
PropertiesFactoryBean
spring对于属性文件有自己的管理方式,通过spring的管理,可以直接使用@Value的方式直接得到属性值。
先使用org.springframework.beans.factory.config.PropertiesFactoryBean对属性配置文件进行管理。
<!-- 使用注解注入properties中的值 -->
<bean id="setting"
class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="locations">
<list>
<value>classpath:*.properties</value>
<value>file:config/*.conf</value>
</list>
</property>
<!-- 设置编码格式 -->
<property name="fileEncoding" value="UTF-8"></property>
</bean>
/**
* config.properties文件映射类
*
*/
@Component("configProperty")
public class ConfigProperty {
/** 作者名字 */
@Value("#{setting[author_name]}")
private String authorName;
/** 项目信息 */
@Value("#{setting[project_info]}")
private String projectInfo;
public String getAuthorName() {
return authorName;
}
public void setAuthorName(String authorName) {
this.authorName = authorName;
}
public String getProjectInfo() {
return projectInfo;
}
public void setProjectInfo(String projectInfo) {
this.projectInfo = projectInfo;
}
}
public class ConfigPropertyTest {
@Resource(name = "configProperty")
private ConfigProperty configProperty;
/**
* 测试Spring注解获取properties文件的值
*/
@Test
public void test() {
System.out.println(configProperty.getAuthorName());
System.out.println(configProperty.getProjectInfo());
}
}
使用org.springframework.beans.factory.config.PropertiesFactoryBean获取属性的方式是:
@Value("${beanid['properties_key']}")
<!-- 设置编码格式 -->
<property name="fileEncoding" value="UTF-8"></property>
————————————————
版权声明:本文为CSDN博主「HelloWorld搬运工」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/wufaliang003/article/details/75208647
网友评论