@Enable模块原理
注解实现
通过@Import加载配置类
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(HelloWorldConfiguration.class)
public @interface EnableHelloWorldAnotation {
}
@SpringBootTest
@EnableHelloWorldAnotation
@Log4j2
class BtApplicationTests {
@Autowired
private String say;
@Test
void contextLoads() {
log.debug(say);
System.out.println(say);
}
}
接口方式实现
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(HelloWorldConfigurationSelector.class)
public @interface EnableHelloWorldAnotation {
}
public class HelloWorldConfigurationSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
return new String[]{HelloWorldConfiguration.class.getName()};
}
}
条件装配
profile方式实现
application.properties:
spring:
profiles:
active: dev,female
public interface SayHelloService {
public void say();
}
@Service
@Profile("male")
public class MaleSayHelloServiceImpl implements SayHelloService {
@Override
public void say() {
System.out.println("hey you!");
}
}
@Service
@Profile("female")
public class FemaleSayHelloServiceImpl implements SayHelloService {
@Override
public void say() {
System.out.println("hi there");
}
}
@SpringBootTest
@Log4j2
class DemoApplicationTests {
@Autowired
private SayHelloService sayHelloService;
@Test
void contextLoads() throws JsonProcessingException {
sayHelloService.say();
}
}
@conditional方式
@Configuration
public class HelloConfiguration {
@Bean
@ConditionalOnSystemProperty(name = "user.name", value = "yetin")
public String aaa() {
return "hello world";
}
}
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.METHOD })
@Documented
@Conditional(OnSystemPropertyCondition.class)
public @interface ConditionalOnSystemProperty {
/**
* Java 系统属性名称
* @return
*/
String name();
/**
* Java 系统属性值
* @return
*/
String value();
}
public class OnSystemPropertyCondition implements Condition {
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
Map<String, Object> annotationAttributes = annotatedTypeMetadata.getAnnotationAttributes(ConditionalOnSystemProperty.class.getName());
String propertyName = String.valueOf(annotationAttributes.get("name"));
String propertyValue = String.valueOf(annotationAttributes.get("value"));
String javaPropertyValue = System.getProperty(propertyName);
return propertyValue.equals(javaPropertyValue);
}
}
@SpringBootTest
@Log4j2
class DemoApplicationTests {
@Autowired
private String aaa;
@Test
void contextLoads() throws JsonProcessingException {
System.out.println(aaa);
}
}
自动装配原理
1.创建resources/META-INF/spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.demo.configurations.HelloWorldAutoConfiguration
2.添加@EnableAutoConfiguration注解读取 resources/META-INF/spring.factories
@EnableAutoConfiguration
public class EnableAutoConfigurationBootstrap {
public static void main(String[] args) {
ConfigurableApplicationContext context = new SpringApplicationBuilder(EnableAutoConfigurationBootstrap.class)
.web(WebApplicationType.NONE)
.run(args);
// helloWorld Bean 是否存在
String helloWorld =
context.getBean("aaa", String.class);
System.out.println("helloWorld Bean : " + helloWorld);
// 关闭上下文
context.close();
}
}
3.创建HelloWorldAutoConfiguration:
@Configuration // Spring 模式注解装配
@EnableHelloWorld // Spring @Enable 模块装配
@ConditionalOnSystemProperty(name = "user.name", value = "yetin") // 条件装配
public class HelloWorldAutoConfiguration {
}
4.enable注解加载HelloConfiguration:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(HelloConfiguration.class)
//@Import(HelloWorldImportSelector.class)
public @interface EnableHelloWorld {
}
public class HelloConfiguration {
@Bean
public String aaa() {
return "hello world";
}
}