spring-boot-autoconfigure之自建starter的调试

喜夏-厌秋 提交于 2020-03-03 07:57:46

starter的创建

这里就不多说了,网络上有挺多简单创建的教程

实现配置

配置文件

EmailConfiguration

@ConfigurationProperties(prefix = "exception.email")  
public class EmailConfiguration {  
  private String sender; 
  private String host;
  private String pwd;
  .....省略getter/setter
  }

需要注入的Service

EmailUtil

@Slf4j  
@Component  
public class EmailUtil {  
  
  //无界任务队列 LinkedBlockingQueue  public static ExecutorService emailExePool =new  
  ThreadPoolExecutor(1, 10, 1000, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());  
  
  private String sender;  
  private String host;  
  private String pwd;  
  public EmailUtil(String sender, String host, String pwd) {  
  this.sender = sender;  
  this.host = host;  
  this.pwd = pwd;  
 }

autoConfigure自动配置

@Configuration  
@EnableConfigurationProperties(value = {EmailConfiguration.class,AspectConfiguration.class})
@ConditionalOnClass(value = {EmailUtil.class})
public class AutoConfigrutionClass {
  @Autowired
  private EmailConfiguration emailConfiguration;
  @Autowired
  private AspectConfiguration aspectConfiguration;  
  @Bean  
  @ConditionalOnProperty(name = "exception.scan.packages")  
  public DefaultPointcutAdvisor defaultPointcutAdvisor() {  
 	StringBuilder baseRoot = new StringBuilder();  
  	baseRoot.append("execution(*");  
  	baseRoot.append(aspectConfiguration.getPackages());  
  	baseRoot.append(".*(..))");  
  
  	ExceptionHandler handler = new ExceptionHandler();  
  	AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();  
  	pointcut.setExpression(baseRoot.toString());  
  	DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor();  
  	advisor.setPointcut(pointcut);  
  	advisor.setAdvice(handler);  
  	return advisor;  
 	}  
 @Bean  
 @ConditionalOnProperty(prefix = "exception.ui",value = "enabled",havingValue = "true")  
  public UIController getUIController() {  
 	 return new UIController();  
 }
 @Bean  
 @ConditionalOnProperty(prefix = "exception.email",name = {"sender","host","pwd"})  
  public EmailUtil getEmailService(){  
	  return new EmailUtil(emailConfiguration.getSender(),emailConfiguration.getHost(),emailConfiguration.getPwd());  
 }
 .......省略
 }

注意EmailUtil,EmailConfiguration中, 这里基于@ConditionalOnProperty中扫描到的配置来实现bean的注入

自动配置

我目前知道的自动配置有两种方式

  • 第一种 基于resource/META-INF的spring.factories(自己创建)
org.springframework.boot.autoconfigure.EnableAutoConfiguration=
#你的配置文件
  • 第二种 实现一个注解,引用@Import
@Retention(RetentionPolicy.RUNTIME)  
@Target(ElementType.TYPE)  
@Import(AutoConfigrutionClass.class)  
public @interface EnableExceptionCatcher {  
  
}

在导入的SpringBoot项目启动文件中

  
@EnableExceptionCatcher  
@SpringBootApplication  
public class SpringApplcation {  
  public static void main(String\[\] args) {  
  SpringApplication.run(SpringApplcation.class, args);  
 }}

自动配置优先级

@AutoConfigureBefore,@AutoConfigureOrder,@AutoConfigureAfter

调试

调试有一个重点,关于bean的初始化顺序 如果初始早了或者晚了可能会导致循环依赖中的bean出错

找到org.springframework.beans.factory.support下的DefaultListableBeanFactory.class

private volatile List<String\> beanDefinitionNames = new ArrayList(256);

beanDefinitionNames字段保存有排好序所有待spring容器加载的beanName

其父类AbstractAutowireCapableBeanFactory下的doCreateBean打下断点,调试出初始顺序来判断是否需要在@Bean下加@ConditionalOnMissingBean。 来增强bean的优先初始化

bean的实例创建步骤

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!