【Java】Springinit-method和@PostConstruct原理我们知道如果想要⾃定义bean的初始化⾏为,有两种⽅法:
1)使⽤xml配置
在bean的xml定义中指定init-method属性。
2)注解配置
在bean的class定义中添加@PostConstruct注解。
例⼦:
xml如下配置:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="www.springframework/schema/beans"
xmlns:xsi="www.w3/2001/XMLSchema-instance"
xsi:schemaLocation="www.springframework/schema/beans www.springframework/schema/beans/spring-beans.xsd">
<bean id = "school" class="del.School" init-method="init"></bean>
</beans>
程序:股票入门基础知识
public class School {
public void init(){
System.out.println("xml init-method");
}
}
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("l");
输出:
xml init-method
Process finished with exit code 0
如果使⽤注解⽅式:
@Component
public class School {
@PostConstruct
public void init(){
System.out.println("annotation PostConstruct");
}
}
抠门的男人ApplicationContext applicationContext = new AnnotationConfigApplicationContext(School.class);
输出:
annotation PostConstruct
Process finished with exit code 0
原理部分
xml原理
肯定是在解析bean定义的时候处理的,xml⽂件的解析在中有提到过。最终会⾛到⼀个BeanDefinitionParrDelegate类,该类负责转发xml的标签到合适的处理器,详细的就不说了,直接看和init-method有关的。
这该类中定义了很多字符串常量:
public static final String NAME_ATTRIBUTE = "name";
public static final String BEAN_ELEMENT = "bean";
public static final String META_ELEMENT = "meta";
public static final String ID_ATTRIBUTE = "id";
public static final String PARENT_ATTRIBUTE = "parent";
public static final String CLASS_ATTRIBUTE = "class";
public static final String ABSTRACT_ATTRIBUTE = "abstract";
public static final String SCOPE_ATTRIBUTE = "scope";
public static final String LAZY_INIT_ATTRIBUTE = "lazy-init";
public static final String AUTOWIRE_ATTRIBUTE = "autowire";
public static final String AUTOWIRE_CANDIDATE_ATTRIBUTE = "autowire-candidate";
public static final String PRIMARY_ATTRIBUTE = "primary";
public static final String DEPENDENCY_CHECK_ATTRIBUTE = "dependency-check";
public static final String DEPENDS_ON_ATTRIBUTE = "depends-on";
public static final String INIT_METHOD_ATTRIBUTE = "init-method";
public static final String DESTROY_METHOD_ATTRIBUTE = "destroy-method";
public static final String FACTORY_METHOD_ATTRIBUTE = "factory-method";
public static final String FACTORY_BEAN_ATTRIBUTE = "factory-bean";
public static final String CONSTRUCTOR_ARG_ELEMENT = "constructor-arg";
public static final String INDEX_ATTRIBUTE = "index";
public static final String TYPE_ATTRIBUTE = "type";
public static final String VALUE_TYPE_ATTRIBUTE = "value-type";
public static final String KEY_TYPE_ATTRIBUTE = "key-type";
public static final String PROPERTY_ELEMENT = "property";
public static final String REF_ATTRIBUTE = "ref";
public static final String VALUE_ATTRIBUTE = "value";
public static final String LOOKUP_METHOD_ELEMENT = "lookup-method";
public static final String REPLACED_METHOD_ELEMENT = "replaced-method";
public static final String REPLACER_ATTRIBUTE = "replacer";
public static final String ARG_TYPE_ELEMENT = "arg-type";
public static final String ARG_TYPE_MATCH_ATTRIBUTE = "match";
public static final String REF_ELEMENT = "ref";
public static final String IDREF_ELEMENT = "idref";
public static final String BEAN_REF_ATTRIBUTE = "bean";
public static final String LOCAL_REF_ATTRIBUTE = "local";
public static final String PARENT_REF_ATTRIBUTE = "parent";
public static final String VALUE_ELEMENT = "value";
public static final String NULL_ELEMENT = "null";
public static final String ARRAY_ELEMENT = "array";
public static final String LIST_ELEMENT = "list";
public static final String SET_ELEMENT = "t";
public static final String MAP_ELEMENT = "map";
public static final String ENTRY_ELEMENT = "entry";
public static final String KEY_ELEMENT = "key";
public static final String KEY_ATTRIBUTE = "key";
public static final String KEY_REF_ATTRIBUTE = "key-ref";
public static final String VALUE_REF_ATTRIBUTE = "value-ref";
public static final String PROPS_ELEMENT = "props";
public static final String PROP_ELEMENT = "prop";
public static final String MERGE_ATTRIBUTE = "merge";
public static final String QUALIFIER_ELEMENT = "qualifier";
public static final String QUALIFIER_ATTRIBUTE_ELEMENT = "attribute";
public static final String DEFAULT_LAZY_INIT_ATTRIBUTE = "default-lazy-init";特殊的反义词是什么
public static final String DEFAULT_MERGE_ATTRIBUTE = "default-merge";
public static final String DEFAULT_AUTOWIRE_ATTRIBUTE = "default-autowire";
public static final String DEFAULT_DEPENDENCY_CHECK_ATTRIBUTE = "default-dependency-check";
public static final String DEFAULT_AUTOWIRE_CANDIDATES_ATTRIBUTE = "default-autowire-candidates";
public static final String DEFAULT_INIT_METHOD_ATTRIBUTE = "default-init-method";
public static final String DEFAULT_DESTROY_METHOD_ATTRIBUTE = "default-destroy-method";
⾥⾯就有init-method,顺着这个变量看,该变量出现在了这个⽅法⾥,该⽅法会在解析xml时被调⽤,由于调⽤链很长,这⾥就不展⽰了:
public AbstractBeanDefinition parBeanDefinitionAttributes(Element ele, String beanName,
BeanDefinition containingBean, AbstractBeanDefinition bd) {
if (ele.hasAttribute(SCOPE_ATTRIBUTE)) {
bd.Attribute(SCOPE_ATTRIBUTE));
}
el if (containingBean != null) {
// Take default from containing bean in ca of an inner bean definition.
bd.Scope());
}
if (ele.hasAttribute(ABSTRACT_ATTRIBUTE)) {
bd.tAbstract(TRUE_VALUE.Attribute(ABSTRACT_ATTRIBUTE)));
}
String lazyInit = Attribute(LAZY_INIT_ATTRIBUTE);
if (DEFAULT_VALUE.equals(lazyInit)) {
lazyInit = LazyInit();
}
bd.tLazyInit(TRUE_VALUE.equals(lazyInit));
String autowire = Attribute(AUTOWIRE_ATTRIBUTE);
二年级上册语文教案bd.tAutowireMode(getAutowireMode(autowire));
String dependencyCheck = Attribute(DEPENDENCY_CHECK_ATTRIBUTE);
bd.tDependencyCheck(getDependencyCheck(dependencyCheck));
if (ele.hasAttribute(DEPENDS_ON_ATTRIBUTE)) {
String dependsOn = Attribute(DEPENDS_ON_ATTRIBUTE);
bd.kenizeToStringArray(dependsOn, MULTI_VALUE_ATTRIBUTE_DELIMITERS));
}
String autowireCandidate = Attribute(AUTOWIRE_CANDIDATE_ATTRIBUTE);
if ("".equals(autowireCandidate) || DEFAULT_VALUE.equals(autowireCandidate)) {
String candidatePattern = AutowireCandidates();
if (candidatePattern != null) {
String[] patterns = aDelimitedListToStringArray(candidatePattern);
bd.tAutowireCandidate(PatternMatchUtils.simpleMatch(patterns, beanName));
}
}
el {
bd.tAutowireCandidate(TRUE_VALUE.equals(autowireCandidate));
}
if (ele.hasAttribute(PRIMARY_ATTRIBUTE)) {
bd.tPrimary(TRUE_VALUE.Attribute(PRIMARY_ATTRIBUTE)));
}
if (ele.hasAttribute(INIT_METHOD_ATTRIBUTE)) {
String initMethodName = Attribute(INIT_METHOD_ATTRIBUTE);
if (!"".equals(initMethodName)) {
bd.tInitMethodName(initMethodName);
}
}
el {
if (InitMethod() != null) {
if (InitMethod() != null) {
小学六年级演讲稿bd.tInitMethodName(InitMethod());
bd.tEnforceInitMethod(fal);
}
}
if (ele.hasAttribute(DESTROY_METHOD_ATTRIBUTE)) {
String destroyMethodName = Attribute(DESTROY_METHOD_ATTRIBUTE);
if (!"".equals(destroyMethodName)) {
bd.tDestroyMethodName(destroyMethodName);
}
}
el {
if (DestroyMethod() != null) {
bd.tDestroyMethodName(DestroyMethod());
bd.tEnforceDestroyMethod(fal);
}
}
云南茶if (ele.hasAttribute(FACTORY_METHOD_ATTRIBUTE)) {
bd.Attribute(FACTORY_METHOD_ATTRIBUTE));
}
if (ele.hasAttribute(FACTORY_BEAN_ATTRIBUTE)) {
bd.Attribute(FACTORY_BEAN_ATTRIBUTE));
}
return bd;
}
主要就是这段代码了:
if (ele.hasAttribute(INIT_METHOD_ATTRIBUTE)) {
String initMethodName = Attribute(INIT_METHOD_ATTRIBUTE);
if (!"".equals(initMethodName)) {
bd.tInitMethodName(initMethodName);
}
}
将xml的bean定义中的init-method⽅法写⼊到AbstractBeanDefinition的实例中。
那么,这个⽅法何时被调⽤呢?
在springbean⼯⼚的核⼼⽅法doCreateBean内部被调⽤的:
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) { // Instantiate the bean.
BeanWrapper instanceWrapper = null;十大名校
1615年
if (mbd.isSingleton()) {
instanceWrapper = ve(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = (instanceWrapper != null ? WrappedInstance() : null);
Class<?> beanType = (instanceWrapper != null ? WrappedClass() : null);
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcesd) {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
mbd.postProcesd = true;
}
}