spring-接口大全
1. InitializingBean
1. 简介
InitializingBean接口为bean提供了初始化方法的方式,它只包括afterPropertiesSet方法,凡是继承该接口的类,在初始化bean的时候都会执行该方法。
2. 使用
@Component public class MyInitBean implements InitializingBean { public void afterPropertiesSet() throws Exception { System.out.println("这是一个 InitializingBean 执行。。。。。"); } }
https://blog.csdn.net/qq_37705525/article/details/124808168
2. FactoryBean
1. 简介
FactoryBean 是 Spring 框架中的一个接口,它可以创建和管理其他对象的实例。通过实现 FactoryBean 接口,可以自定义对象的创建过程。
2. 使用
FactoryBean 源码
public interface FactoryBean<T> { // 获取由此工厂创建的对象实例 T getObject() throws Exception; // 获取由此工厂创建的对象实例的类型 Class<?> getObjectType(); // 判断由此工厂创建的对象实例是否为单例模式 default boolean isSingleton() { return true; } }
@Component public class MyInitBean implements FactoryBean<Dog> { public Dog getObject() throws Exception { return new Dog(); } public Class<?> getObjectType() { return Dog.class; } public boolean isSingleton() { return true; } }
其实会生成两个 Bean,此时根据名称 myInitBean
获取的是 Dog 实例,根据 &myInitBean
获取的才是 MyInitBean 实例。
https://blog.csdn.net/wangshuai6707/article/details/130717923
3. BeanFactoryPostProcessor
1. 简介
- BeanFactoryPostProcessor的执行是Spring Bean生命周期非常重要的一部分;
- BeanFactory级别的后置处理器,在Spring生命周期内,org.springframework.beans.factory.config.BeanFactoryPostProcessor#postProcessBeanFactory只会执行一次;
- 允许在容器读取到Bean的BeanDefinition数据之后,bean未实例化前,读取BeanDefiniion数据,并且可以根据需要进行修改;
2. 使用
@Component public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor { public void postProcessBeanFactory(ConfigurableListableBeanFactory factory) throws BeansException { BeanDefinition dog = factory.getBeanDefinition("dog"); MutablePropertyValues propertyValues = dog.getPropertyValues(); propertyValues.add("name", "pz"); } }
4. BeanDefinitionRegistryPostProcessor
1. 简介
- postProcessBeanDefinitionRegistry()方法可以通过BeanDefinitionRegistry对BeanDefintion进行增删改查;
- 继承了BeanFactoryPostProcessor,BeanFactoryPostProcessor是容器级别的扩展接口,org.springframework.beans.factory.config.BeanFactoryPostProcessor#postProcessBeanFactory方法在容器实例化后、刷新容器前被执行,即在容器刷新前还可以对BeanDefintion再作一些操作;
总结起来就是,在所有的BeanDefinition加载完成之后,Bean真正被实例化之前,可以通过实现BeanDefinitionRegistryPostProcessor接口,对BeanDefinition再做一些定制化的操作,比如修改某个bean的BeanDefinition的属性、手动注册一些复杂的Bean。
2. 使用
@Component public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor { public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { //手工定义一个beanDefinition实例 RootBeanDefinition beanDefinition = new RootBeanDefinition(); //给beanDefinition填充属性 beanDefinition.setBeanClass(Dog.class); MutablePropertyValues propertyValues = new MutablePropertyValues(); PropertyValue propertyValue1 = new PropertyValue("name", "旺财"); PropertyValue propertyValue2 = new PropertyValue("color", "黑色"); PropertyValue propertyValue3 = new PropertyValue("age", 17); propertyValues.addPropertyValue(propertyValue1); propertyValues.addPropertyValue(propertyValue2); propertyValues.addPropertyValue(propertyValue3); beanDefinition.setPropertyValues(propertyValues); //注册手工定义的beanDefinition registry.registerBeanDefinition("dog", beanDefinition); } public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { //根据类名取出手工注册的beanDefinition BeanDefinition beanDefinition = beanFactory.getBeanDefinition("dog"); System.out.println(beanDefinition.getBeanClassName()); //根据类从容器中取出手工注册的beanDefinition所描述的实例bean Dog dog = beanFactory.getBean(Dog.class); System.out.println(this.getClass() + "-" + dog); dog.setName("peizhen"); } }
5. ImportBeanDefinitionRegistrar
1. 简介
描述:ImportBeanDefinitionRegistrar接口是也是spring的扩展点之一,它可以支持我们自己写的代码封装成BeanDefinition对象,注册到Spring容器中,功能类似于注解@Service @Component。
很多三方框架集成Spring的时候,都会通过该接口,实现扫描指定的类,然后注册到spring容器中,比如Mybatis中的Mapper接口,springCloud中的FeignClient接口,都是通过该接口实现的自定义注册逻辑。
2. 使用
1. 简单使用
@Data public class Dog { private String name; private Integer age; private String color; @Override public String toString() { return "Dog{" + "name='" + name + '\'' + ", age=" + age + ", color='" + color + '\'' + '}'; } }
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions(AnnotationMetadata am, BeanDefinitionRegistry registry) { //1、通过Bd工具类生成bd对象,只是这个Db对象比较纯洁没有绑定任何类 BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(); GenericBeanDefinition beanDefinition = (GenericBeanDefinition) beanDefinitionBuilder.getBeanDefinition(); //2、设置bd绑定的类型 beanDefinition.setBeanClass(Dog.class); //3、注册到spring容器中 registry.registerBeanDefinition("myDog",beanDefinition); } }
@SpringBootApplication @Import(MyImportBeanDefinitionRegistrar.class) public class StartMain { public static void main(String[] args) { ConfigurableApplicationContext run = SpringApplication.run(StartMain.class, args); Dog dog = run.getBean(Dog.class); System.out.println(dog); } }
这样效果就相当于 @Service、@Component 注解
6. ObjectProvider
ObjectProvider 是在 Spring 4.3 版本引入的一个接口,用于在Spring框架中获取对象实例。
package com.demo.component; import com.demo.pojo.Dog; import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.List; import java.util.stream.Collectors; @Component public class ObjectProviderComponent { //注入 ObjectProvider 对象 @Autowired private ObjectProvider<Dog> dogObjectProvider; /** * 获取此类型可用 bean,没有或者多个都抛异常 * */ public void getObject(){ //获取实例对象, 没有就报错 Dog object = dogObjectProvider.getObject(); System.out.println(object); } /** * 获取此类型可用 bean,没有返回 null,多个抛异常 * */ public void getIfAvailable(){ //获取实例对象,不存在返回 null Dog ifAvailable = dogObjectProvider.getIfAvailable(); System.out.println(ifAvailable); //获取实例对象,不存就创建一个 Dog ifAvailable1 = dogObjectProvider.getIfAvailable(() -> new Dog("wpz", "pink", 30)); System.out.println(ifAvailable1); } /** * 如果此类型 bean 有一个或者多个,就返回 null * */ public void getUnique(){ //获取唯一对象 Dog ifUnique = dogObjectProvider.getIfUnique(); System.out.println(ifUnique); //获取唯一对象,没有就创建一个 Dog ifUnique1 = dogObjectProvider.getIfUnique(() -> new Dog("wpz", "pink", 29)); System.out.println(ifUnique1); } /** * 以流的方式获取此类型 bean * */ public void stream(){ List<Dog> collect = dogObjectProvider.stream().collect(Collectors.toList()); System.out.println(collect); } }
7. Aware
Spring框架中的Aware接口主要用于让Bean在初始化时能够获取到Spring容器提供的某些特定服务或上下文信息,从而使Bean具有对Spring容器环境的感知能力。
Aware 接口本身没有任何方法,属于标记接口,可以通过子接口获取不同的用途。
-
BeanNameAware: 允许Bean知道自己的名称(即在配置文件或注解中定义的Bean ID)。通过实现setBeanName(String beanName)方法,Bean可以获得其在Spring容器中的名称。
-
BeanFactoryAware: 提供给Bean访问Spring容器的BeanFactory。通过实现setBeanFactory(BeanFactory beanFactory)方法,Bean可以获取到BeanFactory的引用,进而有能力访问容器中的其他Bean或执行Bean工厂级别的操作。
-
ApplicationContextAware: 这是最常用的之一,它允许Bean获得Spring的ApplicationContext(应用上下文)。通过实现setApplicationContext(ApplicationContext applicationContext)方法,Bean能够访问到容器中的所有服务,包括消息解析、事件发布、资源加载等。
-
ResourceLoaderAware: 允许Bean访问ResourceLoader,从而能够加载外部资源,如文件或类路径资源。
-
EnvironmentAware: 使Bean能够访问到Environment对象,进而获取到应用的运行环境配置信息,如属性文件中的配置值。
-
MessageSourceAware: 使得Bean能够访问到MessageSource,用于国际化和本地化的消息处理。
@Component public class BeanFactoryAwareDemo implements BeanFactoryAware { BeanFactory beanFactory; @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { this.beanFactory = beanFactory; } public <T> T getBean(String beanName, Class<T> c){ return beanFactory.getBean(beanName, c); } } @Component(value = "wpz") public class Dog { public void sayName(){ System.out.println("im wpz!"); } } @SpringBootTest(classes = SpringDemoMain.class) public class AwareTest { @Autowired private BeanFactoryAwareDemo bd; @Test public void test(){ Dog dog = bd.getBean("wpz", Dog.class); dog.sayName(); } }
@Component public class BeanNameAwareDemo implements BeanNameAware { @Override public void setBeanName(String s) { System.out.println("这是我的名字:" + s); } } @SpringBootTest(classes = SpringDemoMain.class) public class AwareTest { @Autowired private BeanFactoryAwareDemo beanFactoryAwareDemo; }
8. ApplicationContextInitializer ??
9. ResourcePatternResolver
ResourcePatternResolver 资源匹配接口。在 spring
的 AnnotationConfigApplicationContext.scan()
方法,以及 mybatis 的 MybatisProperties 类发现 mapper 中都有使用。
实现类 PathMatchingResourcePatternResolver 是一个Ant模式通配符的Resource查找器,可以用来解析资源文件,主要是用来解析类路径下的资源文件。当然它也可以用来解析其它资源文件,如基于文件系统的本地资源文件。
1. 获取文件系统文件
public void test1(){ PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); //获取的是项目根目录下的文件 Resource resource = resolver.getResource("file:ReadMe.md"); print(resource, "file:相对路径"); //磁盘绝对路径 Resource resource1 = resolver.getResource("file:D:\\test.js"); print(resource1, "file:磁盘绝对路径"); }
2. 获取类路径下文件
public void test2(){ PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); //读取资源目录 resource 下文件 Resource resource = resolver.getResource("application.properties"); print(resource, "无前缀 resource"); //如果不是根目录,也可以指定目录 Resource resource1 = resolver.getResource("file/pz.txt"); print(resource1, "无前缀带目录 resource"); //也可以明确指定 classpath Resource resource2 = resolver.getResource("classpath:file/pz.txt"); print(resource2, "classpath 带目录 resource"); //这里是获取编译后的 Resource resource3 = resolver.getResource("com/demo/aware/Dog.class"); print(resource3, "class 文件"); }
3. 获取所有类路径下
public void test3() throws IOException { PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); //读取资源目录 resource 下文件 Resource[] resource = resolver.getResources("classpath*:META-INF/spring.factories"); for(Resource resource1:resource) { print(resource1, "classpath* resource"); } }
4. 通配符
/** * 得配合 classpath* * */ public void test4() throws IOException { PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); //文件名匹配 Resource[] resources = resolver.getResources("classpath*:file/p*.txt"); for(Resource resource : resources) { print(resource, "文件名通配符"); } //单个路径匹配 * 匹配一层目录 Resource[] resources1 = resolver.getResources("classpath*:*/pz.txt"); for(Resource resource : resources1) { print(resource, "单个路径通配符"); } //多个路径匹配 ** 匹配多层目录 Resource[] resources2 = resolver.getResources("classpath*:**/pz.txt"); for(Resource resource : resources2) { print(resource, "多个路径通配符"); } }
10. BeanUtils
Spring 提供的 bean 工具类。
1. 方法
public static <T> T instantiateClass(Class<T> clazz) 通过反射返回一个实例
11. Metadata
Metadata 表示元数据,就是数据的数据,org.springframework.core.type包名下。两个顶级接口:ClassMetadata
和 AnnotatedTypeMetadata
1. ClassMetadata
ClassMetadata,顾名思义,就是表示 Java 中 类 的元数据
- 类名;
- 是否是注解;
- 是否是接口;
- 是否抽象类;
- 父类;
- 实现的接口等;
2. AnnotatedTypeMetadata
这个接口表示的是注解元素 (AnnotatedElement) 的元数据,我们常见的Class、Method、Constructor、Parameter等等都属于它的子类都属于注解元素。简单理解:只要能在上面标注注解的元素都属于这种元素。
3. AnnotationMetadata
这是理解 Spring 注解编程的必备知识,它是 ClassMetadata 和 AnnotatedTypeMetadata 的子接口,具有两者共同能力,并且新增了访问注解的相关方法。可以简单理解为它是对注解的抽象。
经常这么使用得到注解里面所有的属性值:
AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(annoMetadata, annType);
12. 获取 controller 位置
13. RequestMappingHandlerMapping
可以获取所有 Controller 相关信息,包括 jar 包中的,用来找 controller 挺好用
@Autowired private RequestMappingHandlerMapping requestMappingHandlerMapping; @PostConstruct public void logControllerPath(){ Map<RequestmappingInfo, handlerMethod> handlermethods = requestMappingHandlerMapping.getHandlerMethods(); handlerMethods.forEach((key, value) ->{ System.out.println("controller path" + key + "---" + value.getBeanType().getName() + "---" + value.getMethod().getName()) }) }
本文作者:primaryC
本文链接:https://www.cnblogs.com/cnff/p/18156913
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步