springboot的Initializer的使用:
package com.hurricane.learn.springboot.standard.initializer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.ApplicationContextInitializer; import org.springframework.context.ConfigurableApplicationContext; /** * 因为这个类的initialize方法调用是在spring容器中的bean还没有开始初始化的时刻, * 因此,通过@Component注解是无法使其生效的。<br/> * 使用方式有两种,分别为:<br/> * 1.application.addInitializers(new MyApplicationContextInitializer()); * 2.将org.springframework.context.ApplicationContextInitializer=com.hurricane.learn.springboot.initializer.MyApplicationContextInitializer * 放置到META-INF/spring.factories文件中 * @author Hurricane * @date 2018年4月8日 * @version 1.0 */ public class MyApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext>{ private static final Logger logger = LoggerFactory.getLogger(MyApplicationContextInitializer.class); @Override public void initialize(ConfigurableApplicationContext context) { logger.debug("========MyApplicationContextInitializer initialize============="); } }
第一种添加Initializer的方式为:
SpringApplication application = new SpringApplication(App.class); application.addInitializers(new MyApplicationContextInitializer()); ConfigurableApplicationContext context = application.run(args);
springboot的Listener的使用:
event定义:
package com.hurricane.learn.springboot.standard.event; import org.springframework.context.ApplicationEvent; public class MyEvent extends ApplicationEvent{ private static final long serialVersionUID = 1L; public MyEvent(Object source) { super(source); } }
listener的定义:
package com.hurricane.learn.springboot.standard.listener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.ApplicationListener; import org.springframework.context.event.ContextClosedEvent; import com.hurricane.learn.springboot.standard.event.MyEvent; /** * 使用方式有两种,分别为:<br/> * 1.application.addListeners(new MyApplicationListener()); * 2.org.springframework.context.ApplicationListener=com.hurricane.learn.springboot.listener.MyApplicationListener * @author Hurricane * @date 2018年4月8日 * @version 1.0 */ public class MyApplicationListener implements ApplicationListener<MyEvent>{ private static final Logger logger = LoggerFactory.getLogger(MyApplicationListener.class); @Override public void onApplicationEvent(MyEvent event) { logger.debug("=======event为:{}=========",event); } }
使用spring的上下文进行event的发布:
package com.hurricane.learn.springboot.standard; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ConfigurableApplicationContext; import com.hurricane.learn.springboot.standard.event.MyEvent; @SpringBootApplication public class App { public static void main(String[] args) { ConfigurableApplicationContext context = SpringApplication.run(App.class, args); context.publishEvent(new MyEvent("myevent")); context.close(); } }
添加listener的方式与添加Initializer的方式类似。
springboot内置了一些事件(event)如ContextStoppedEvent,可以通过查看ApplicationEvent类的继承关系来选择使用。
springboot的ApplicationRunner与CommandLineRunner的使用:
ApplicationRunner的定义:
package com.hurricane.learn.springboot.standard.runner; import java.util.Iterator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.stereotype.Component; /** * 可以识别的参数格式为:--abc=def * @author Hurricane * @date 2018年4月8日 * @version 1.0 */ @Component public class MyApplicationRunner implements ApplicationRunner{ private static final Logger logger = LoggerFactory.getLogger(MyApplicationRunner.class); @Override public void run(ApplicationArguments args) throws Exception { logger.debug("=====MyApplicationRunner 传入参数有:{}=====",args.getOptionNames()); Iterator<String> iterator = args.getOptionNames().iterator(); while (iterator.hasNext()) { String string = (String) iterator.next(); logger.debug("=====MyApplicationRunner 参数名{}:参数值:{}=====",string,args.getOptionValues(string)); } } }
CommandLineRunner的定义:
package com.hurricane.learn.springboot.standard.runner; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.CommandLineRunner; import org.springframework.stereotype.Component; /** * 可以识别的参数格式为:--abc=def * @author Hurricane * @date 2018年4月8日 * @version 1.0 */ @Component public class MyCommandLineRunner implements CommandLineRunner{ private static final Logger logger = LoggerFactory.getLogger(MyCommandLineRunner.class); @Override public void run(String... args) throws Exception { for (String string : args) { logger.debug("=====MyCommandLineRunner 传入参数有:{}=====",string); } } }
ApplicationRunner与CommandLineRunner的功能(解析传入参数)类似,只是对于传入参数--abc=def aa --dd=ff bb,
ApplicationRunner会忽略掉aa、bb两个参数,只是用--abc=def --dd=ff,并解析为参数名与参数值。
扫描二维码关注公众号,回复:
1584201 查看本文章
而对于CommandLineRunner会简单地输出传入的参数,将空格作为参数的分隔符。
为了让ApplicationRunner与CommandLineRunner起作用,只需要将他们放置到spring的容器中即可。
springboot的@Import注解的使用:
1.定义一个注解:
package com.hurricane.learn.springboot.standard.config.annotation; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.springframework.context.annotation.Import; import com.hurricane.learn.springboot.standard.config.selector.LogSelector; /** * 注入的spring容器中的bean若在指定包下,则进行日志输出 * @author Hurricane * @date 2018年4月9日 * @version 1.0 */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @Import(LogSelector.class) public @interface EnableLog { String[] packages(); }
2.编写一个与该注解配合使用的Selector类:
package com.hurricane.learn.springboot.standard.config.selector; import java.util.Arrays; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.context.annotation.ImportSelector; import org.springframework.core.type.AnnotationMetadata; import org.springframework.stereotype.Component; import org.springframework.util.MultiValueMap; @Component public class LogSelector implements ImportSelector,BeanPostProcessor{ private static final Logger logger = LoggerFactory.getLogger(LogSelector.class); private static String[] packages; @Override public String[] selectImports(AnnotationMetadata importingClassMetadata) { MultiValueMap<String, Object> allAnnotationAttributes = importingClassMetadata.getAllAnnotationAttributes("com.hurricane.learn.springboot.standard.config.annotation.EnableLog"); List<Object> list = allAnnotationAttributes.get("packages"); String[] object = (String[]) list.get(0); packages = object; logger.info("LogSelector 将bean加入到spring容器中"); return new String[]{"com.hurricane.learn.springboot.standard.entity.Product","com.hurricane.learn.springboot.standard.entity.User"}; } @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if (packages!=null) for (int i = 0; i < packages.length; i++) { if (bean.getClass().getName().startsWith(packages[i])) { logger.debug("bean:{} 初始化开始.",beanName); } } return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (packages!=null) for (int i = 0; i < packages.length; i++) { if (bean.getClass().getName().startsWith(packages[i])) { logger.debug("bean:{} 初始化结束.",beanName); } } return bean; } }
LogSelector只需实现ImportSelector接口即可,但是为了实现指定的功能(输出指定包下注入到spring的bean),这里同时实现了BeanPostProcessor接口。
使用上面的@EnableLog注解:
package com.hurricane.learn.springboot.standard; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ConfigurableApplicationContext; import com.hurricane.learn.springboot.standard.config.annotation.EnableLog; import com.hurricane.learn.springboot.standard.config.selector.LogSelector; @EnableLog(packages="com.hurricane") @SpringBootApplication public class App { public static void main(String[] args) { ConfigurableApplicationContext context = SpringApplication.run(App.class, args); LogSelector bean = context.getBean(LogSelector.class); System.out.println(bean); context.close(); } }
单独使用@Import注解时,注意:
* 注解@Import会把value指定的class导入到spring容器中,但是如果指定的class实现了ImportSelector接口, * 则不会将自身导入到spring容器中,但是ImportSelector接口中selectImports方法返回的值(类的全路径)会导入到spring容器中