Spring Boot 的核心注解SpringBootApplication引起的探究
星期二, 2019-12-03 | Author: Lee | JAVA-and-J2EE, spring-boot | 1,399 views
Spring Boot 的核心注解SpringBootApplication引起的探究
1.Spring Boot 的核心注解是哪个?
先上一个工程的启动配置项看下:
项目比较老混杂了spring boot,dubbo,jersey注册等
package com.pomelolee.cms; import com.ctrip.framework.apollo.spring.annotation.EnableApolloConfig; import com.pomelolee.boot.dubbo.annotation.EnableDubboProvider; import org.glassfish.jersey.server.ResourceConfig; import org.glassfish.jersey.servlet.ServletProperties; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.web.support.SpringBootServletInitializer; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.netflix.feign.EnableFeignClients; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider; import org.springframework.context.annotation.ImportResource; import org.springframework.util.ClassUtils; import java.util.HashSet; import java.util.Set; @EnableFeignClients @SpringBootApplication @EnableApolloConfig @EnableDiscoveryClient @EnableDubboProvider @ImportResource("classpath*:/META-INF/spring/spring-job.xml") public class Application extends SpringBootServletInitializer { public static void main(String[] args) { SpringApplication.run(Application.class, args); } @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(Application.class); } @Bean public ResourceConfig resourceConfig() { ResourceConfig resourceConfig = new ResourceConfig(); ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(true); Set<BeanDefinition> beanDefinitionSet = scanner.findCandidateComponents("com.pomelolee.cms.service"); beanDefinitionSet.addAll(scanner.findCandidateComponents("com.pomelolee.cms.facade")); beanDefinitionSet.addAll(scanner.findCandidateComponents("com.pomelolee.cms.config")); Set<Class<?>> clazzSet = new HashSet<Class<?>>(); for (BeanDefinition beanDefinition : beanDefinitionSet) { clazzSet.add( ClassUtils.resolveClassName( beanDefinition.getBeanClassName(), resourceConfig.getClassLoader())); } resourceConfig.registerClasses(clazzSet); resourceConfig.property(ServletProperties.FILTER_FORWARD_ON_404, true); return resourceConfig; } } |
@SpringBootApplication 注解,就是 Spring Boot 的核心注解。
org.springframework.boot.autoconfigure.@SpringBootApplication 注解的代码如下:
// SpringBootApplication.java @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @SpringBootConfiguration @EnableAutoConfiguration @ComponentScan( excludeFilters = {@Filter( type = FilterType.CUSTOM, classes = {TypeExcludeFilter.class} ), @Filter( type = FilterType.CUSTOM, classes = {AutoConfigurationExcludeFilter.class} )} ) public @interface SpringBootApplication { @AliasFor( annotation = EnableAutoConfiguration.class ) Class<?>[] exclude() default {}; @AliasFor( annotation = EnableAutoConfiguration.class ) String[] excludeName() default {}; @AliasFor( annotation = ComponentScan.class, attribute = "basePackages" ) String[] scanBasePackages() default {}; @AliasFor( annotation = ComponentScan.class, attribute = "basePackageClasses" ) Class<?>[] scanBasePackageClasses() default {}; } |
它组合了 3 个注解
@Configuration 注解,指定类是 Bean 定义的配置类。
@Configuration 注解,来自 spring-context 项目,用于 Java Config ,不是 Spring Boot 新带来的。
#ComponentScan 注解,扫描指定包下的 Bean 们。
@ComponentScan 注解,来自 spring-context 项目,用于 Java Config ,不是 Spring Boot 新带来的。
@EnableAutoConfiguration 注解,打开自动配置的功能。如果我们想要关闭某个类的自动配置,可以设置注解的 exclude 或 excludeName 属性。
@EnableAutoConfiguration 注解,来自 spring-boot-autoconfigure 项目,它才是 Spring Boot 新带来的。
2.什么是 Spring Boot 自动配置?
上面我们已经看到,使用 @EnableAutoConfiguration 注解,打开 Spring Boot 自动配置的功能。
这个才是自动装配的核心,那些start的启动包都是依赖这个做完成和注入到容器中的,如果你写个start的时候就一切都懂了.
2.1:Spring Boot 在启动时扫描项目所依赖的 jar 包,寻找包含在 META-INF/spring.factories 文件的 jar 包。
2.2:根据 META-INF/spring.factories 配置加载 AutoConfigure 类。
2.3:根据 @Conditional 等条件注解 的条件,进行自动配置并将 Bean 注入 Spring IoC 中。
3.如果自定义frame下的自动注入?
上面提到的注解类:
EnableDubboProvider.java:
package com.pomelolee.boot.dubbo.annotation; import java.lang.annotation.Annotation; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target({java.lang.annotation.ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface EnableDubboProvider {} |
此 DubboProviderAutoConfiguration.java 为配置在spring.factories的自动类
package com.pomelolee.boot.dubbo; import com.alibaba.dubbo.config.annotation.Service; import com.pomelolee.boot.dubbo.annotation.EnableDubboProvider; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.ImportResource; @Configuration @ConditionalOnClass({Service.class}) @ConditionalOnBean(annotation={EnableDubboProvider.class}) @ImportResource(locations={"classpath*:dubbo/*-provider.xml"}) public class DubboProviderAutoConfiguration {} |
消费者注解类:EnableDubboConsumer.java
package com.pomelolee.boot.dubbo.annotation; import java.lang.annotation.Annotation; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target({java.lang.annotation.ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface EnableDubboConsumer {} |
消费者提供者注入类:DubboConsumerAutoConfiguration
package com.pomelolee.boot.dubbo; import com.pomelolee.boot.dubbo.annotation.EnableDubboConsumer; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.ImportResource; @Configuration @ConditionalOnBean(annotation={EnableDubboConsumer.class}) @ImportResource(locations={"classpath*:dubbo/*-consumer.xml"}) public class DubboConsumerAutoConfiguration {} |
需要加载的配置文件:dubbo/dubbo-provider.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <dubbo:application name="${spring.application.name}" owner="${dubbo.application.owner}" organization="${dubbo.application.organization}"/> <dubbo:registry protocol="${dubbo.registry.protocol:zookeeper}" client="${dubbo.registry.client:curator}" address="${dubbo.registry.address}"/> <dubbo:protocol name="dubbo" server="netty" port="${dubbo.protocol.port}"/> <!--<dubbo:monitor protocol="registry"/>--> <!--<dubbo:provider filter="DubboExceptionFilter"/>--> <dubbo:annotation package="${dubbo.annotation.package}"/> </beans> |
需要加载的配置文件:dubbo/dubbo-consumer.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <dubbo:application name="${spring.application.name}" owner="${dubbo.application.owner}" organization="${dubbo.application.organization}" /> <dubbo:registry protocol="${dubbo.registry.protocol:zookeeper}" client="${dubbo.registry.client:curator}" address="${dubbo.registry.address}" /> <!--<dubbo:monitor protocol="registry" />--> <dubbo:annotation /> </beans> |
配置启动文件:META-INF/spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.pomelolee.boot.dubbo.DubboProviderAutoConfiguration,\ com.pomelolee.boot.dubbo.DubboConsumerAutoConfiguration |
配置提供者:ETA-INF/spring.handlers
http\://code.alibabatech.com/schema/dubbo=com.alibaba.dubbo.config.spring.schema.DubboNamespaceHandler |
小结: 以上总结自网络等,如有雷同还望海涵.
文章作者: Lee
本文地址: https://www.pomelolee.com/1957.html
除非注明,Pomelo Lee文章均为原创,转载请以链接形式标明本文地址
No comments yet.
Leave a comment
Search
相关文章
热门文章
最新文章
文章分类
- ajax (10)
- algorithm-learn (3)
- Android (6)
- as (3)
- computer (85)
- Database (30)
- disucz (4)
- enterprise (1)
- erlang (2)
- flash (5)
- golang (3)
- html5 (18)
- ios (4)
- JAVA-and-J2EE (186)
- linux (143)
- mac (10)
- movie-music (11)
- pagemaker (36)
- php (50)
- spring-boot (2)
- Synology群晖 (2)
- Uncategorized (6)
- unity (1)
- webgame (15)
- wordpress (33)
- work-other (2)
- 低代码 (1)
- 体味生活 (40)
- 前端 (21)
- 大数据 (8)
- 游戏开发 (9)
- 爱上海 (19)
- 读书 (4)
- 软件 (3)