总结一下Spring以及SpringBoot出现的一些接口和注解
ApplicationContextAware接口类
这个接口是Spring暴露给外面获取ApplicationContext上下文,获取bean实例的一个接口。在项目中一般定义一个工具类,继承这个接口,从而可以直接通过工具类获取Bean实例
@Component
public class SpringApplicationUtil implements ApplicationContextAware {
public static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringApplicationUtil.applicationContext = applicationContext;
}
public static HttpServletRequest getHttpServletRequest() {
return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
}
}
InitializingBean接口类
这个接口是初始化Bean的时候会触发这个接口的实现方法,可以把一些初始化的操作放在接口里面去做。
@Component
ublic class DemoBean implements InitializingBean {
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("我被初始化啦,啦啦啦");
}
}
FactoryBean接口类
这个是一个工厂Bean,也是一个面试高频问点。主要是里面有一个getObject方法,可以在这个方法里面定义一些复杂类的初始化,在一些源码里面用得非常之多,例如在Mybatis整合Spring的源码中,最后如何把一个Mapper接口怎样把代理类放进Spring容器的,就是采用的getObject的方法移花接木。
@Component
public class DemoBean implements FactoryBean {
@Override
public DemoBean getObject() throws Exception {
return null;
}
@Override
public Class<?> getObjectType() {
return null;
}
}
SmartLifecycle接口类
这个方法是Spring容器初始化完成后会去触发这个接口类,这个接口在大量的源码中也能看到,例如在Nacos里面,也是在这个实现类里面发起服务注册的,如果在项目中要实现类似的场景不妨实时这个类
@Component
public class TestSmartLifecycle implements SmartLifecycle {
@Override
public void start() {
}
@Override
public boolean isRunning() {
return false;
}
@Override
public void stop() {
isRunning = false;
}
}
ApplicationRunner接口
这个是Spring Boot容器加载完会触发,对于SpringBoot项目,初始化的内容也可以放在这里面做
BeanPostProcessor接口
这个接口是在Bean加载完成会触发这个方法
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return null;
}
这个类的方法可以拦截到每一个bean初始化过后的对象,适合在这里做一些Bean的解析或者增强操作,我在项目中使用这个对一些对象的注解进行解析,放在Map里面,这样就能扫描到所有标记过注解的类,进行一些业务操作
@PostConstruct注解
效果类似于InitializingBean,这个注解标识的方法在初始化的时候会调用这个方法,比如下面这段代码。
@PostConstruct
public void init(){
LoginBiz.loginClass.put(getLoginType().getCode(),this);
}
@Qualifier注解
这个是Spring提供的一个注解,在Ribbon的源码里面用到过这个注解,在@LoadBalanced注解上面使用@Qualifier
@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Qualifier
public @interface LoadBalanced {
}
标注在每一个RestTemplet上面,就能LoadBalancerAutoConfiguration里面就能Bean里面获取到所有RestTemplate集合
@Configuration(
proxyBeanMethods = false
)
@ConditionalOnClass({RestTemplate.class})
@ConditionalOnBean({LoadBalancerClient.class})
@EnableConfigurationProperties({LoadBalancerRetryProperties.class})
public class LoadBalancerAutoConfiguration {
@LoadBalanced
@Autowired(
required = false
)
private List<RestTemplate> restTemplates = Collections.emptyList();
....
}
@Import注解
这个注解大量的框架源码都在使用,可以用这个注解导入一些配置类,如在SpringBoot自动装配中使用
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class<?>[] exclude() default {};
String[] excludeName() default {};
}
导入了AutoConfigurationImportSelector类,里面配置了大量的Bean
@Conditional注解
条件装配,标识Spring中有这个Bean才进行装配,没有就不装配,这个也在大量源码中出现,表示在一定条件下才对类进行装配。如在Ribbon源码里面
@Bean
@ConditionalOnMissingBean({LoadBalancerClient.class})
public LoadBalancerClient loadBalancerClient() {
return new RibbonLoadBalancerClient(this.springClientFactory());
}
@Bean
@ConditionalOnClass(
name = {"org.springframework.retry.support.RetryTemplate"}
)
@ConditionalOnMissingBean
public LoadBalancedRetryFactory loadBalancedRetryPolicyFactory(final SpringClientFactory clientFactory) {
return new RibbonLoadBalancedRetryFactory(clientFactory);
}
...
等等一大堆方法都会有这个注解