Spring接口
FactoryBean接口
Spring中有两种类型的Bean:一种是普通的JavaBean;另一种就是工厂Bean(FactoryBean),这两种Bean都受Spring的IoC容器管理。
FactoryBean 是一个特殊的bean,要想得到FactoryBean本身,必须通过&FactoryBeanName,可以在BeanFactory中通过getBean(&FactoryBeanName)来得到 FactoryBean。
一般来说我们自己写的Bean在只继承自己的接口时创建Bean的过程是交给IOC容器来实现的。但是某些特殊情况如果单纯的交给Spring的IOC容器来实现会配置非常复杂有时甚至没办法实现。所以这种情况下Spring为我们提供了FactoryBean这个接口来实现这个创建的过程。
public interface FactoryBean<T> { //获取FactoryBean初始化的Bean实例 T getObject() throws Exception; //获取Bean实例的类型 Class<?> getObjectType(); //判断是否是单例模式 boolean isSingleton(); }
示例:
@Component public class MyBean implements FactoryBean { private String message; public MyBean() { this.message = "通过构造方法初始化实例"; } @Override public Object getObject() throws Exception { MyBean myBean = new MyBean(); // 这里可以做一些复杂的操作,比如解析资源等IOC没办法实现的情况 // 这里并不一定要返回MyBean自身的实例,可以是其他任何对象的实例如:SqlSessionFactory return myBean; } @Override public Class<?> getObjectType() { return MyBean.class; } @Override public boolean isSingleton() { return false; } }
BeanFactory接口
BeanFactory有三个是子类:AutowireCapableBeanFactory,HierarchicalBeanFactory,ListableBeanFactory。最终的默认实现类是 DefaultListableBeanFactory。
BeanFactory接口是Spring bean容器(也就是IoC容器)的核心根接口,主要是用于创建bean的工厂接口,其定义的接口方法分为以下几个部分:获取bean实例、判断容器中是否包含某个bean、判断实例是否为单列模式或则原型模式、类型匹配、实例类型、获取别名。
// 用于区分FactoryBean实例,列如:如果myJndiObject是一个FactoryBean,通过 &myJndiObject获取返回的是工厂,而不是工厂返回的实例。 String FACTORY_BEAN_PREFIX = "&"; // 获取bean Object getBean(String name) throws BeansException; <T> T getBean(String name, Class<T> requiredType) throws BeansException; Object getBean(String name, Object... args) throws BeansException; <T> T getBean(Class<T> requiredType) throws BeansException; <T> T getBean(Class<T> requiredType, Object... args) throws BeansException; // 获取bean的提供者(对象工厂) <T> ObjectProvider<T> getBeanProvider(Class<T> requiredType); <T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType); boolean containsBean(String name); // 是否包含指定名字的bean boolean isSingleton(String name) throws NoSuchBeanDefinitionException; // 是否为单例 boolean isPrototype(String name) throws NoSuchBeanDefinitionException; // 是否为原型 // 指定名字的bean是否和指定的类型匹配 boolean isTypeMatch(String name, ResolvableType typeToMatch); boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException; Class<?> getType(String name) throws NoSuchBeanDefinitionException; // 获取指定名字的bean的类型 String[] getAliases(String name); // 获取指定名字的bean的所有别名
BeanDefinition
管理每个bean的定义信息,容器启动的时候,spring会将配置文件中定以的信息或则使用注解(如@Componet @Service @Controller等)定义的bean封装成一个个 BeanDefinition 对象,每个bean对应一个BeanDefinition对象,在对象实例化期间,使用bean对应的BeanDenifition对象通过反射生成实例对象。BeanDefinition接口方法用来管理bean的属性信息。
BeanDefinition接口中的属性信息跟xml配置文件中的标签中的属性一一对应,也就是说一个BeanDefinition对应一个标签信息。在容器启动的时候,就会先将标签信息解析封装成BeanDefinition接口实现类对象。
BeanDefinition有一个子接口 AnnotatedBeanDefinition;三个间接实现类,分别是RootBeanFactory、ChildBeanFactory和GenericBeanDefinition。其中RootBeanFactory是用来封装父类定义信息(没有显示继承其他类的类)、ChildBeanDefinition是用来封装子类定义信息。
BeanDefinitionRegistry接口
定义了关于 BeanDefinition 的注册、移除、查询等一系列的操作。BeanDefinition 注册的容器为 DefaultListableBeanFactory下 beanDefinitionMap
/** Map of bean definition objects, keyed by bean name. */ private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256); /** Map from bean name to merged BeanDefinitionHolder. */ private final Map<String, BeanDefinitionHolder> mergedBeanDefinitionHolders = new ConcurrentHashMap<>(256); /** Map of singleton and non-singleton bean names, keyed by dependency type. */ private final Map<Class<?>, String[]> allBeanNamesByType = new ConcurrentHashMap<>(64); /** Map of singleton-only bean names, keyed by dependency type. */ private final Map<Class<?>, String[]> singletonBeanNamesByType = new ConcurrentHashMap<>(64); /** List of bean definition names, in registration order. */ private volatile List<String> beanDefinitionNames = new ArrayList<>(256);
BeanDefinitionRegistryPostProcessor接口
BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子接口,用于动态注册、修改、移除beanDefinitionMap的BeanDefinition
//修改应用程序上下文的内部bean定义注册表,在所有Bean定义将要被加载,Bean实例还未创建的时候运行,它优先于postProcessBeanFactory方法执行。 void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry);
public class test { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Appconfig.class); } } //自定义BeanDefinitionRegistryPostProcessor实现注册、移除、修改BeanDefinition class CustomBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor { @Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { System.out.println("---->postProcessBeanDefinitionRegistry容器中BeanDefinition的数量为:" + registry.getBeanDefinitionCount()); RootBeanDefinition beanDefinition = new RootBeanDefinition(Person.class); // 还可以这样给容器中注册 //Bean AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Dog.class).getBeanDefinition(); registry.registerBeanDefinition("person", beanDefinition); } //这是继承父类BeanFactoryPostProcessor的方法 @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames(); for (String str : beanDefinitionNames) { System.out.println("----->" + str); } System.out.println("====>postProcessBeanFactory容器中BeanDefinition的数量为:" + beanFactory.getBeanDefinitionCount()); } } @Component class Appconfig { @Bean public CustomBeanDefinitionRegistryPostProcessor customBeanDefinitionRegistryPostProcessor() { return new CustomBeanDefinitionRegistryPostProcessor(); } }
BeanFactoryPostProcessor接口
BeanFactoryPostProcessor允许修改容器中的BeanDefinitions ,但不允许触发Bean的实例化;这样做可能会导致bean实例化过早,从而违反了容器并造成了意外的副作用。如果需要bean实例交互,请使用BeanPostProcessor。
副作用1——使用注解进行依赖注入失败;
副作用2——可能会将ApplicationContext容器启动过程暴露在多线程之下;
可以配置多个BeanFactoryPostProcessor的实现类,通过”order”控制执行次序,值越大优先级越低(要实现Ordered接口)
//BeanFactoryPostProcessor是在 Bean定义加载完成之后,Bean实例初始化之前会调用postProcessBeanFactory方法 void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
public class test { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Appconfig.class); Person person = (Person)context.getBean("person"); System.out.println(person.toString()); } } @Component public class Appconfig { @Bean public CustomBeanDefinitionRegistryPostProcessor customBeanDefinitionRegistryPostProcessor() { return new CustomBeanDefinitionRegistryPostProcessor(); } @Bean public CustomBeanFactoryPostProcessor customBeanFactoryPostProcessor(){ return new CustomBeanFactoryPostProcessor(); } @Bean public Person person(){ Person person = new Person(); person.setName("张三"); return person; } } public class CustomBeanFactoryPostProcessor implements BeanFactoryPostProcessor { @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { int count = beanFactory.getBeanDefinitionCount(); String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames(); for (String beanName : beanDefinitionNames) { if ("person".equals(beanName)) { BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName); MutablePropertyValues m = beanDefinition.getPropertyValues(); m.addPropertyValue("name", "赵四"); System.out.println("--修改了name属性初始值了"); } } } } @Bean public Person person(){ Person person = new Person(); person.setName("张三"); return person; }
BeanPostProcessor接口
Spring的AOP代理就是作为BeanPostProcessor实现.
BeanPostProcessor主要是在类初始化的前后处理相应的事,必须在普通对象创建之前被创建。
可以配置多个BeanPostProcessor的实现类,通过”order”控制执行次序,值越大优先级越低(要实现Ordered接口)
先执行的是postProcessBeforeInitialization,然后是afterPropertiesSet,然后是init-method,然后是postProcessAfterInitialization。
//在任何bean初始化回调(如InitializingBean 或自定义init-method)之前 Object postProcessBeforeInitialization(Object bean, String beanName) //在任何bean初始化回调(如InitializingBean 或自定义init-method)之后 Object postProcessAfterInitialization(Object bean, String beanName)
public class test { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Appconfig.class); Person person = (Person)context.getBean("person"); System.out.println(person.toString()); } } @Configuration public class Appconfig { // 提示信息: is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) // 对于返回Spring BeanFactoryPostProcessor(BFPP)类型或者BeanPostProcessor(BPP)类型的@Bean方法,必须特别注意。 // 因为BFPP对象必须在容器生命周期的早期实例化,所以它们会干扰@Configuration类中的@Autowired,@ Value和@PostConstruct之类的注释的处理。 // 为了避免这些生命周期问题,请将BFPP或BPP返回的@Bean方法标记为static @Bean public static CustomBeanPostProcessor customBeanPostProcessor(){ return new CustomBeanPostProcessor(); } @Bean public Person person(){ Person person = new Person(); person.setName("张三"); return person; } } public class CustomBeanPostProcessor implements BeanPostProcessor { public CustomBeanPostProcessor() { System.out.println("CustomBeanPostProcessor 实例化......"); } @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("spring中bean实例:" + beanName + " 初始化之前处理......"); return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("spring中bean实例:" + beanName + " 初始化之后处理......"); if ("person".equals(beanName)){ Field[] declaredFields = bean.getClass().getDeclaredFields(); for (Field declaredField : declaredFields) { if ("name".equals(declaredField.getName())){ try { //修改对象的属性 declaredField.setAccessible(true); declaredField.set(bean,"哈哈哈"); } catch (IllegalAccessException e) { e.printStackTrace(); } } } } return bean; } }
注意点:
(一)BeanPostProcessor依赖的bean,不会执行BeanPostProcessor的方法,因为所依赖的Bean需要在BeanPostProcessor之前创建完成!
(二)BeanPostProcessor以及依赖的bean无法使用AOP!
 (三)当使用ConfigurableBeanFactory接口的addBeanPostProcessor方法手动添加BeanPostProcessor时,只能作用于那些延迟加载的Bean或非单例bean!
(四)当使用addBeanPostProcessor方式添加的BeanPostProcessor,Ordered接口的作用将失效,而是以注册的顺序执行!
(五)在使用@Bean声明工厂方法返回BeanPostProcessor实现类对象时,返回值必须是BeanPostProcessor类型,或者更低级的类型!
InstantiationAwareBeanPostProcessor接口
InstantiationAwareBeanPostProcessor接口继承了BeanPostProcess接口,区别如下:
BeanPostProcess接口只在bean的初始化阶段进行扩展(注入spring上下文前后),而InstantiationAwareBeanPostProcessor接口在此基础上增加了3个方法,把可扩展的范围增加了实例化阶段和属性注入阶段。
//实例化bean之前,如果该方法返回null,后面的方法都正常执行,如果不为null,则直接执行postProcessAfterInitialization方法,(实例化之后 和 初始化之前都不执行) Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException; //实例化bean之后,如果该方法返回false,并且不需要check,那么postProcessProperties就会被忽略不执行;如果返回true,postProcessProperties就会被执行 boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException; //bean已经实例化完成,可以对属性值进行修改(这个时候属性值还未被设置,但是我们可以修改原本该设置进去的属性值) PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException
public class Test { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Appconfig.class); Object person = context.getBean("person"); System.out.println(person.toString()); } } @Configuration class Appconfig { @Bean public CustomInstantiationAwareBeanPostProcessor customInstantiationAwareBeanPostProcessor(){ return new CustomInstantiationAwareBeanPostProcessor(); } @Bean public Person person(){ Person person = new Person(); person.setName("张三"); return person; } } public class CustomInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor { @Override public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { System.out.println("--->postProcessBeforeInstantiation");//顺序1 return null; } @Override public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException { System.out.println("--->postProcessAfterInstantiation");//顺序2 return true; } @Override public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException { System.out.println("--->postProcessProperties");//顺序3 return pvs; } @Override public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException { System.out.println("--->postProcessPropertyValues"); return pvs; } @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("--->postProcessBeforeInitialization");//顺序4 return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("--->postProcessAfterInitialization");//顺序5 return bean; } }
BeanFactoryAware接口
实现BeanFactoryAware接口可以直接访问 Spring 容器(BeanFactory)
//可以获取到Spring容器 void setBeanFactory(BeanFactory beanFactory) throws BeansException;
public class Main { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Appconfig.class); Object person = CustomBeanFactoryAware.getBean("person"); System.out.println(person.toString()); } } @Configuration class Appconfig { @Bean public CustomBeanFactoryAware customBeanFactoryAware(){ return new CustomBeanFactoryAware(); } @Bean public Person person(){ Person person = new Person(); person.setName("张三"); return person; } } public class CustomBeanFactoryAware implements BeanFactoryAware { private static BeanFactory bff; public static void setContextBean(BeanFactory bf){ bff=bf; } public static Object getContextBean(String beanName){ return bff.getBean(beanName); } @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { CustomBeanFactoryAware.setContextBean(beanFactory); } public static Object getBean(String beanName){ return CustomBeanFactoryAware.getContextBean(beanName); } }
ApplicationContextAware接口
实现ApplicationContextAware接口可以直接获得Spring上下文管理器(ApplicationContext),使用方法参考BeanFactoryAware接口
EnvironmentAware接口
用于获取EnviromentAware的一个扩展类,可以获得系统内的所有参数,使用方法参考BeanFactoryAware接口
ResourceLoaderAware接口
用于获取ResourceLoader的一个扩展类,获取classpath内所有的资源对象,使用方法参考BeanFactoryAware接口
EmbeddedValueResolverAware接口
用于获取StringValueResolver的一个扩展类,StringValueResolver用于获取基于String类型的properties的变量,使用方法参考BeanFactoryAware接口
MessageSourceAware接口
用于获取MessageSource的一个扩展类,MessageSource主要用来做国际化,使用方法参考BeanFactoryAware接口
ApplicationEventPublisherAware接口
用于获取ApplicationEventPublisher的一个扩展类,ApplicationEventPublisher可以用来发布事件,结合ApplicationListener来共同使用。
ApplicationContextInitializer接口
用于在spring容器refresh()刷新之前初始化Spring ConfigurableApplicationContext的回调接口,允许我们对ConfigurableApplicationContext的实例做进一步的设置和处理。例如,根据上下文环境注册属性源或激活配置文件等。
- ApplicationContextInitializer支持Order注解,表示执行顺序,越小越早执行;
//初始化给定的应用程序上下文 void initialize(C applicationContext);
@Order(1) class CustomApplicationContextInitializer implements ApplicationContextInitializer { @Override public void initialize(ConfigurableApplicationContext applicationContext) { System.out.println("-----MyApplicationContextInitializer initialize-----"); // 打印人所有 beanName System.out.println(applicationContext.getBeanDefinitionCount() + "个Bean的名字如下:"); Arrays.stream(applicationContext.getBeanDefinitionNames()).forEach(System.out::println); //从容器中获取环境变量组件 ConfigurableEnvironment environment = applicationContext.getEnvironment(); //自己自定义一些属性放在map集合中 Map<String, Object> map = new HashMap<>(); map.put("key1", "value1"); //包装为MapPropertySource组件 MapPropertySource mapPropertySource = new MapPropertySource("firstInitializer", map); //存到环境变量中去 environment.getPropertySources().addLast(mapPropertySource); System.out.println("FirstInitializer属性注册成功...");
//注册后置处理器
applicationContext.addBeanFactoryPostProcessor(new CustomBeanDefinitionRegistryPostProcessor());
}
}
三种实现方式:
①SpringBoot方式
@SpringBootApplication public class SpringBootStudyApplication { public static void main(String[] args) { SpringApplication springApplication = new SpringApplication(SpringBootStudyApplication.class); //手动注册初始化器 springApplication.addInitializers(new CustomApplicationContextInitializer()); springApplication.run(args); } }
②resources目录下新建application.properties方式
#initializer
context.initializer.classes = com.yue.config.CustomApplicationContextInitializer
③resources目录下新建META-INF/spring.factories方式
org.springframework.context.ApplicationContextInitializer = com.yue.config.CustomApplicationContextInitializer
SmartInitializingSingleton接口
可以对所有单例对象(非懒加载对象)初始化完毕后,做一些后置的业务处理。
CommandLineRunner / ApplicationRunner接口
整个项目启动完毕后,自动执行。如果有多个CommandLineRunner,可以利用@Order来进行排序。
 
                    
                     
                    
                 
                    
                
 
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号