blade中后处理器逻辑的实现,WebContextListener实现
Bean后处理器会在Bean实例化结束后(注意,该实例化应该是指Bean类的实例化,还没有进行spring中的注入等操作,并不是Spring最终返回的Bean),对其进行近一步的增强处理。
spring中提供一些Aware结尾相关接口,像是BeanFactoryAware、 BeanNameAware、ApplicationContextAware、ResourceLoaderAware、ServletContextAware等等。
实现这些 Aware接口的Bean在被实例化之后,可以取得一些相对应的资源,例如实现BeanFactoryAware的Bean在实例化后,Spring容器将会注入BeanFactory的实例,而实现ApplicationContextAware的Bean,在Bean被实例化后,将会被注入ApplicationContext的实例等等。
其实这个blade也是模仿了spring中的这个处理逻辑,在获得了bean的实例之后,还没有处理注入依赖的时候,对bean进行增强处理,如获取当前容器中IOC的引用之类的处理,做你想做的事情吧。
- 之前IocApplication中判断某个类是否有注解有很多的if else如果没有注解我们就需要去判断是否含有某个接口啦!
List<BeanProcessor> processors = CollectionKit.newArrayList();
List<ClassInfo> ctxClasses = CollectionKit.newArrayList(8);
List<ClassInfo> processoers = CollectionKit.newArrayList(8);
处理的逻辑,这里还没有看到如何处理路由
Class<?>[] interfaces = clazz.getInterfaces();
for (Class<?> in : interfaces) {
if (in.equals(Interceptor.class)) {
ioc.addBean(clazz);
routeBuilder.addInterceptor(clazz);
} else if (in.equals(WebContextListener.class)) {
ctxClasses.add(c);
} else if (in.equals(BeanProcessor.class)) {
processoers.add(c);
}
}
WebContextListener 这个不是监听启动的那个时候,然后进行初始化处理动作,这个是自定义的监听器,很方便的传入参数。我们也可以使用哦!
import com.blade.config.BConfig;
import javax.servlet.ServletContext;
// BaseConfig Interface, Implements Object can be auto execut
public interface WebContextListener {
void init(BConfig bConfig, ServletContext sec);
}
BeanProcessor 这个后处理器就是在注入Ioc之前,向类实例中调用这个方法,哈哈!传递Ioc资源的引用
public interface BeanProcessor {
void register(Ioc ioc);
}
- 获取到了所有的 List< ClassInfo> processoers = CollectionKit.newArrayList(8);之后需要将这个加入Ioc然后获取到实例,调用实例的方法
List<BeanProcessor> processors = CollectionKit.newArrayList();
List<ClassInfo> ctxClasses = CollectionKit.newArrayList(8);
List<ClassInfo> processoers = CollectionKit.newArrayList(8);
//获取实例
processoers.forEach(c -> {
Object bean = ioc.addBean(c.getClazz());
processors.add((BeanProcessor) bean);
});
//调用方法!这里就把,Ioc注入进去了,这个和spring的处理逻辑没有区别
processors.forEach(b -> b.register(ioc));
- listener也是一样的处理逻辑
- private List ctxs = CollectionKit.newArrayList();这个是IOCApplication中的全局变量
ctxClasses.forEach(c -> {
Object bean = ioc.addBean(c.getClazz());
ctxs.add((WebContextListener) bean);
});
IocApplication中的一个方法就是初始化这个listener的方法的,以前我们所有的找包,找class,找注解,注入依赖等等都是IocApplication中的initBeans方法。等所有的bean的依赖注入都实现了再去调用这个监听的方法。
public void initCtx(ServletContext sec) {
ctxs.forEach(c -> c.init(blade.bConfig(), sec));
}
那么这个方法又是如何调用的?昨天不是说嵌入Jetty中不是注入了某个listener?就是这里啊,然后初始化IocApplication,然后初始化Bean 哈哈,创建自定义的Listener,调用方法就好了。
**
* Blade Web Context Listener
*/
public class BladeInitListener implements ServletContextListener, HttpSessionListener {
@Override
public void sessionCreated(HttpSessionEvent event) {
// session time out, default is 15 minutes, unit is minutes
int timeout = $().config().getInt("server.timeout", 15);
event.getSession().setMaxInactiveInterval(timeout * 60);
}
@Override
public void contextInitialized(ServletContextEvent sce) {
Blade blade = Blade.$();
if (!blade.isInit()) {
long initStart = System.currentTimeMillis();
ServletContext servletContext = sce.getServletContext();
String webRoot = DispatchKit.getWebRoot(servletContext);
blade.webRoot(webRoot);
EmbedServer embedServer = blade.embedServer();
if (null != embedServer) {
embedServer.setWebRoot(webRoot);
}
try {
// initialization ioc
IocApplication iocApplication = new IocApplication();
iocApplication.initBeans(); //很多的动作啊!
iocApplication.initCtx(servletContext);
//调用监听的方法哦!
blade.init();
} catch (Exception e) {
LOGGER.error("ApplicationContext init error", e);
}
}
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
WebContextHolder.destroy();
}
@Override
public void sessionDestroyed(HttpSessionEvent event) {
}
完毕,收获一份理解!