1.定义注解
/*
* FileName: PostInit
* Author: AK
* Date: 2019/8/23 0023
*/
package net.ak.server.postInitialize.service;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* 初始化方法注解,相当于 @PostConstruct
* 含有该注解的方法
* (方法不能有参数)
* 会在应用上下文完全构造完成后(全部bean构造和后处理程序完成运行),将按给定的顺序调用
*
* @author AK
* 2019/8/23 0023
*/
@Documented
@Retention(RUNTIME)
@Target(METHOD)
public @interface PostInit {
/**
* 执行方法的顺序
* 默认0
* 从小开始排序,依次执行方法
*/
int order() default 0;
}
2.定义监听器
/*
* FileName: PostInitListener
* Author: AK
* Date: 2019/8/23 0023
*/
package net.ak.server.postInitialize.service;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
/**
* 当容器加载处理完相应的bean之后,使用ApplicationListener<ContextRefreshedEvent>
* 监听被注解(@PostInitialize)的方法
* (方法不能有参数)
*
* @author AK
* 2019/8/23 0023
*/
@Component
public class PostInitListener implements ApplicationListener<ContextRefreshedEvent> {
private static final Logger LOGGER = LogManager.getLogger(PostInitListener.class);
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
LOGGER.info("=== [PostInitListener] Start Work ===");
ApplicationContext applicationContext = event.getApplicationContext();
Map<String, Object> beanMap = applicationContext.getBeansOfType(Object.class, false, true);
if (beanMap == null || beanMap.size() == 0) {
LOGGER.warn("=== [PostInitListener] Not Found ===");
return;
}
List<PostInitParam> postInitParamList = new LinkedList<>();
for (String beanName : beanMap.keySet()) {
Object bean = beanMap.get(beanName);
Class<?> beanClass = bean.getClass();
Method[] methods = beanClass.getMethods();
for (Method method : methods) {
if (getAnnotation(method) == null) {
continue;
}
//判断方法参数
if (method.getParameterTypes().length == 0) {
int order = getAnnotation(method).order();
postInitParamList.add(new PostInitParam(method, bean, order, beanName));
} else {
LOGGER.warn("=== [PostInitListener] Method({}.{}) Can't Have Any Arguments ===", method.toGenericString(), beanName);
}
}
}
if (postInitParamList.size() == 0) {
return;
}
//排序
Collections.sort(postInitParamList);
for (PostInitParam postInitParam : postInitParamList) {
Method method = postInitParam.getMethod();
try {
method.invoke(postInitParam.getBeanInstance());
} catch (Throwable e) {
throw new BeanCreationException("=== [PostInitListener] Init Bean Fail:" + postInitParam.getBeanName() + " ===", e);
}
}
LOGGER.info("=== [PostInitListener] Stop Work ===");
}
private PostInit getAnnotation(Method method) {
do {
if (method.isAnnotationPresent(PostInit.class)) {
return method.getAnnotation(PostInit.class);
}
}
while ((method = getSuperMethod(method)) != null);
return null;
}
private Method getSuperMethod(Method method) {
Class declaring = method.getDeclaringClass();
if (declaring.getSuperclass() != null) {
Class superClass = declaring.getSuperclass();
try {
Method superMethod = superClass.getMethod(method.getName(), method.getParameterTypes());
if (superMethod != null) {
return superMethod;
}
} catch (Exception e) {
return null;
}
}
return null;
}
private class PostInitParam implements Comparable<PostInitParam> {
private Method method;
private Object beanInstance;
private int order;
private String beanName;
private PostInitParam(Method method, Object beanInstance, int order, String beanName) {
this.method = method;
this.beanInstance = beanInstance;
this.order = order;
this.beanName = beanName;
}
private int getOrder() {
return order;
}
private Method getMethod() {
return method;
}
private Object getBeanInstance() {
return beanInstance;
}
private String getBeanName() {
return beanName;
}
@Override
public int compareTo(PostInitParam postInitParam) {
int thisVal = this.order;
int anotherVal = postInitParam.order;
return (Integer.compare(thisVal, anotherVal));
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
PostInitParam that = (PostInitParam) o;
return order == that.order &&
method.equals(that.method) &&
beanName.equals(that.beanName);
}
@Override
public int hashCode() {
return Objects.hash(method, beanInstance, order, beanName);
}
}
}