spring-接口大全

1. InitializingBean

1. 简介

InitializingBean接口为bean提供了初始化方法的方式,它只包括afterPropertiesSet方法,凡是继承该接口的类,在初始化bean的时候都会执行该方法。

2. 使用

demo

@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. 简单使用

一个 pojo 类

@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 + '\'' +
'}';
}
}

实现 ImportBeanDefinitionRegistrar 接口

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);
}
}

使用 @Import 注入

@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 接口本身没有任何方法,属于标记接口,可以通过子接口获取不同的用途。
常用的Aware接口及其用途:

  1. BeanNameAware: 允许Bean知道自己的名称(即在配置文件或注解中定义的Bean ID)。通过实现setBeanName(String beanName)方法,Bean可以获得其在Spring容器中的名称。

  2. BeanFactoryAware: 提供给Bean访问Spring容器的BeanFactory。通过实现setBeanFactory(BeanFactory beanFactory)方法,Bean可以获取到BeanFactory的引用,进而有能力访问容器中的其他Bean或执行Bean工厂级别的操作。

  3. ApplicationContextAware: 这是最常用的之一,它允许Bean获得Spring的ApplicationContext(应用上下文)。通过实现setApplicationContext(ApplicationContext applicationContext)方法,Bean能够访问到容器中的所有服务,包括消息解析、事件发布、资源加载等。

  4. ResourceLoaderAware: 允许Bean访问ResourceLoader,从而能够加载外部资源,如文件或类路径资源。

  5. EnvironmentAware: 使Bean能够访问到Environment对象,进而获取到应用的运行环境配置信息,如属性文件中的配置值。

  6. MessageSourceAware: 使得Bean能够访问到MessageSource,用于国际化和本地化的消息处理。

BeanFactoryAware 示例:

@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();
}
}

BeanNameAware 示例

@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 资源匹配接口。在 springAnnotationConfigApplicationContext.scan() 方法,以及 mybatis 的 MybatisProperties 类发现 mapper 中都有使用。

实现类 PathMatchingResourcePatternResolver 是一个Ant模式通配符的Resource查找器,可以用来解析资源文件,主要是用来解析类路径下的资源文件。当然它也可以用来解析其它资源文件,如基于文件系统的本地资源文件。

1. 获取文件系统文件

file 就表示文件系统目录

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. 获取类路径下文件

无协议或者 classpath 表示类路径下(编译后的 classes 目录)

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. 获取所有类路径下

classpath* 和 classpath 区别在于:classpath前缀只能获取当前类路径下的资源文件,而classpath*前缀可以获取所有类路径下的资源文件,包括jar包中的

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包名下。两个顶级接口:ClassMetadataAnnotatedTypeMetadata

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 中国大陆许可协议进行许可。

posted @   primaryC  阅读(192)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
  1. 1 404 not found REOL
404 not found - REOL
00:00 / 00:00
An audio error has occurred.