首页 > 其他分享 >最全的Spring注解详解

最全的Spring注解详解

时间:2022-10-14 12:41:07浏览次数:41  
标签:容器 Spring 最全 Bean public bean 详解 组件 class

@Configuration : 配置类 == 配置文件,告诉Spring这是一个配置类
@ComponentScan(value="com.atguigu",excludeFilters = {
@Filter(type=FilterType.ANNOTATION,classes={Controller.class})
})
@ComonentScan value : 指定要扫描的包(这个注解可以定义多个)
excludeFilters = Filter[] : 指定扫描的时候按照什么规则排除那些组件
includeFilters = Filter[] : 指定扫描的时候只需要包含那些组件
useDefaultFilters = false : 表示去掉默认扫描
FilterType.ANNOTATION : 按照注解类型 例如 : Controller.class
FilterType.ASSIGNABLE_TYPE : 按照给定的类型 例如 : UserService.class
FilterType.ASPECTJ : 使用ASPECTJ表达式
FilterType.REGEX : 使用正则指定
FilterType.CUSTOM : 使用自定义规则自定义规则需要实现TypeFilter接口
public class MyTypeFilter implements TypeFilter {
/**
metadataReader : 读取到的当前正则扫描的类的信息
metadataReaderFactory : 可以获取到其他任何类的信息
*/
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) {
// 获取当前类注解的信息
AnnotationMetadata annotationMetadate = metadataReader.getAnnontationMetadata();
// 获取当前正在扫描的类的类信息
ClassMetadata classMetadata = metadataReader.getClassMetadata();
// 获取当前类资源(类的路径)
Resource resource = metadataReader.getResource();
// 获取这个类名
String className = classMetadata.getClassName();
// 自定义匹配规则
if(className.contains("er")) {
return true;
}
return false;
}
} @ComponentScans(
value {
@ComponentScan(value="com.atguigu",excludeFilters = {
@Filter(type=FilterType.ANNOTATION,classes={Controller.class})
}, useDefaultFilters = false)
}
) : 里面可以定义多个@ComponentScan@Bean : 给容器中注册一个Bean;类型为返回值的类型,id默认是用方法名作为id
@Scope("") : 表示这个对象或者这个bean的创建作用域范围(调整作用域).
prototype : 多实例的,ioc容器时并不会调用方法创建对象放在容器中.每次获取的时候才会调用方法创建对象.
singleton : 单实例的(默认值),ioc容器启动会调用方法创建对象放到ioc容器中.以后每次获取就是直接从容器(map.get())中拿.
request : 同一次请求创建一个实例
session : 同一个session创建一个实例@Lazy : 懒加载
单实例bean,默认在容器启动的时候创建对象.
懒加载: 容器启动不创建对象,第一次调用(获取)Bean创建对象,并初始化.@Conditional({Condition}) : 按照一定的条件进行判断,满足条件给容器中注册bean(可以放在@Bean上,或者类上)
例如 :
//放在类上统一设置
// 类中组件统一设置,满足当前条件,这个类中配置的所有bean注册才能生效.
@Conditional({WindowsCondition.class})
@Configuration

//实现接口Condition
public class LinuxCondition implements Condition {
/**

*/
public boolean matchs(CondititContext context, AnnotatedTypeMetadata metadada) {
// 是否linux系统
// 1. 能获取到ioc使用的beanFactory
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
// 2.获取类加载器
ClassLoader classLoader = context.getClassLoader();
// 3.获取当前环境信息
Environment environment = context.getEnvironment();
// 4.获取到bean定义的注册类(可以判断容器中的bean注册情况,也可以给容器中注册bean)
BeanDefinitionRegistry registry = context.getRegistry();
// 判断容器中是否包含bean
boolean definition = registry.containsBeanDefinition("persion");

String property = environment.getProperty("os.name");
if (property.contains("linux")){
return true;
}
return false;
}

}

// 获取bean名称
String[] namesForType = applicatinContext.getBeanNamsForType();
// 动态获取环境变量的值,获取容器运行环境例如 : windows,liunx
ConfigurableEnvironment environment = applicationContext.getEnvironment();
// 获取操作系统的名称
String property = environment.getProperty("os.name");

给容器中注册组件 :
1 : 包扫描+组件标注注解(@Controller/@Service/@Repository/@Component)
2 : @Bean[导入的第三方包里面的组件]
3 : @Import[快速给容器中导入一个组件]
1) : @Import(要导入到容器中的组件);容器中就会自动注册这个组件,id默认是组件的全类名(也可以导入多个组件)
2) : ImportSelector : 返回需要导入的组件的全类名数组.
3) : ImportBeanDefinitionRegistrar : 手动注册Bean到容器中
4 : 使用Spring提供的FactoryBean(工厂Bean)
1) : 默认获取到的是工厂bean调用getObject创建的对象
2) : 要获取工厂Bean本身,我们需要给id前面加一个&
&colorFactoryBean

@Import(要导入到容器中的组件 例如 : Color.class) : 方在类上,导入组件,容器中就会自动注册这个组件,id默认是组件的全类名(也可以导入多个组件)
(2) ImportSelector : 返回需要导入的组件的全类名数组.
例如 :
//自定义逻辑返回需要导入的组件
public class MyImportSelector implements ImportSelector {
// 返回值,就是导入到容器中的组件全类名
// AnnotationMetadata : 当前标注@Import注解的类的所有注解信息
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
// 方法不要返回null值
return new String[];
}
}
@Import({Color.class,Red.class,MyImportSelector.class})
(3) ImportBeanDefinitionRegistrar : 手动注册Bean到容器中
例如 :
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
// AnnotationMetadata : 当前类的注解信息
// BeanDefinitionRegistry : BeanDefinitionRegistry注册类;
// 把所有需要添加到容器中的bean : 调用 BeanDefinitionRegistry.registryBeanDefinition手工注册进来
@Override
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry registry) {
// 通过bean名称,判断bean是否在容器中
booean definition = registry.containsBeanDefinition("red");
boolean definition1 = registry.containsBeanDefinition("blue");
if (definition && definition1) {
// 指定bean定义信息 : (Bean的类型,Bean...)
RootBeanDefinition bean = new RootBeanDefinition(RainBow.class);
// 注册一个Bean,指定Bean名
registry.registryBeanDefinition("rainBow", bean);
}
}
}4 : 例子 :
// 创建一个Spring定义的FactoryBean
public class ColorFactoryBean implements FactoryBean<Color> {
// 返回一个Color对象,这个对象会添加到容器中
@Override
public Color getObject() throws Exception {
return new Color();
}

public Class<?> getObjectType() {
return Color.class;
}

//是单例?
//true : 这个bean是单例,在容器中保存一份
//false : 多实例,每次获取都会创建一个新的bean
@Override
public boolean isSingleton() {
return false
}
}

@Bean
public ColorFactoryBean getBean() {
return new ColorFactoryBean();
}

public void test() {
//工厂Bean获取的是调用getObject创建的对象;实际上获取的是Color对象
Object bean2 = applicatinContext.getBean("colorFactoryBean");
//这个是获取的ColorFactoryBean对象,因为在FactoryBean接口中定义了一个字符串,表示以&开头的就是获取实现FactoryBean接口的对象
Object bean3 = applicatinContext.getBean("&colorFactoryBean");
}
Bean的生命周期
bean创建 -- 初始化 -- 销毁的过程
容器管理bean的生命周期 :
我们可以自定义初始化和销毁方法;容器在bean进行到当前生命周期的时候来调用我们自定义的初始化和销毁的方法
构造(对象创建)
单实例 : 在容器启动的时候创建对象
多实例 : 在每次获取的时候创建对象

BeanPostProcessor.postProcessBeforeInitialization
初始化 :
对象创建完成,并赋值好,调用初始化方法...
BeanPostProcessor.postProcessInitialization

销毁 :
单实例 : 容器关闭的时候
多实例 : 容器不会管理者bean,容器不会调用销毁方法.

遍历得到容器中所有的BeanPostProcessor : 挨个执行beforeInitialization,一旦返回null,跳出for循环,不会执行后面的BeanPostProcessor.postProcessBeforeInitialization

BeanPostProcessor的原理
populateBean(beanName, mdb, instanceWrapper) : 给bean进行属性赋值
initializeBean
{
appliyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName)
invokeInitMethods(beanName, wrappedBean, mbd);执行自定义初始化
applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName)
}

1) : 指定初始化和销毁方法:
通过@Bean指定init-method和destory-method;
2) : 通过让Bean实现InitializingBean(定义初始化逻辑),DisposableBean(定义销毁逻辑)
3) : 可以使用JSR250;
@PostConstruct : 在bean创建完成并且属性赋值完成;来执行初始化方法(在对象创建并赋值之后调用)
@PreDestroy : 在容器销毁bean之前通知我们进行清理工作.

例如 :
public class Dog{
public Dog() {
System.out.println("");
}

//对象创建并赋值之后调用
@PostConstruct
public void init() {
System.out.println("11");
}

//容器移除对象之前
@PreDestroy
public void detory(){
}
}
4) : BeanPostProcessor[interface] : bean后置处理器;
在bean初始化前后进行一些处理工作;
postProcessBeforeInitialization : 在初始化之前工作
postProcessInitialization : 在初始化之后工作

Spring底层对BeanPostProcessor的使用 :
bean赋值,注入其他组件,@Autowired,生命周期注解功能。@Async, xxx BeanPostProcessor;

@Value : 给属性赋值。
1. 基本数值 例如 : @Value("111")
2. 可以写SpEL. 例如 : @Value("#{20-2}")
3. 可以写${},取出配置文件中的值(在运行环境变量里面的值) 例如 : @Value("${name}")
@PropertySource读取外部配置文件中的k/v保存到运行的环境变量中;加载完外部的配置文件以后使用${}取出配置文件的值。
例如 :
AnnotationConfigApplicationContext applicatinContext = new AnnontationConfigApplicationContext();
pringBeans(applicationContext);
Person person = (Person)applicationContext.getBean("person");
ConfigurableEnvironment environment = applicatinContext.getEnvironment();
// 这是根路径下的.properties配置文件中的k/v值
Sting property = environment.getProperty("person.nickName);
applicatinContext.close();

自动装配 :
Spring利用依赖注入(DI),完成对IOC容器中各个组件的依赖关系赋值;
1) . 默认优先按照类型去容器中找对应的组件 : applicationContext.getBean(BookDao.class);找到就赋值
2) . 如果找到多个相同类型的组件,再将属性的名称作为组件的id去容器中查找
3) . @Qualifier("bookDao") : 使用@Qualifier指定需要装配的组件的id,而不是使用属性名。
4) . 自动装配默认一定要将属性赋值好,没有就会报错。(可以通过更改属性值.例如 : @Autowired(required=false);这样就在没有这个组件时,不会进行自动装配)
5) . @Primary : 让Spring进行自动装配的时候,默认使用首选的bean;
也可以继续使用@Qualifier指定需要装配的bean的名字。
applicatinContext.getBean("bookDao");
BookService{
@Autowired
BookDao bookDao
}
(2):Spring还支持使用@Resource(JSR250)和@Inject(JSR330)【Java规范的注解】
@Resource
可以和@Autowired一样实现自动装配功能;默认是按照组件名称进行装配的;
没有能支持@Primary功能没有支持 @Autowired(reqiured = false);
@Inject
需要导入javax.inject的包,和Autowired的功能一样。没有required=false的功能;
@Autowired : Spring定义的; @Resouce和@Inject都是java规范。
Spring的@Autowired的底层使用AutowiredAnnotationBeanPostProcessor : 解析完成自动装配功能。
(3):@Autowired : 构造器,参数,方法,属性
@Componetnt : 默认加载ioc容器中的组件,容器启动会调用无参构造器创建对象,再进行初始化赋值等操作
1): 标注在方法位置 : @Bean + 方法参数;参数从容器中获取;默认不写@Autowired效果是一样的,都能自动装配
2): 标注在构造器上 : 如果组件只有一个有参构造器,这个有参构造器的@Autowired可以省略,参数位置的组件换是可以自动从容中获取.
3):标注在参数位置
@Bean标注的方法创建对象的时候,方法参数的值从容器中获取。
(4) : 自定义组件想要使用Spring容器底层的一些组件(ApplicationContext,BeanFactory,xxx);自定义组件实现xxxAware;在创建对象的时候,会调用接口规定的方法注入相关组件;Aware
把Spring底层一些组件注入到自定义的Bean中;
xxxAware: 功能使用xxxProcessor;
ApplicationContextAware ==> ApplicationContextAwareProcessor;
@Profile : 指定组件在哪个环境的情况下才能被注册到容器中。
1) : 加了环境标识的bean,只有这个环境被激活的时候才能注册到容器中。默认是default环境。
2) : 写在配置上,只有是指定的环境的时候,整个配置类里面的所有配置才能开始生效。

激活方式 :
(1) : 使用命令行动态参数 : 在虚拟机参数位置加载 -Dspring.profiles.active=test
(2) :代码的方式激活某种环境。
(3) : 没有标注环境标识的bean在任何环境下都是加载的。
例如 :
AnnotationConfigApplicationContext applicatinContext = new AnnontationConfigApplicationContext();
//1。创建一个applicationContext
//2. 设置需要激活的环境
applicatinContext.getEnvironment().setActiveProfiles("dev");
//3.注册主配置类
applicatinContext.registry(MainConfigOrProfile.class);
//4.启动刷新容器
applicatinContext.refresh();

标签:容器,Spring,最全,Bean,public,bean,详解,组件,class
From: https://blog.51cto.com/u_15829196/5756186

相关文章

  • 详解apt、yum、dnf 和 pkg
    介绍包管理系统除了安装软件外,它还提供了工具来更新已经安装的包。包存储库有助于确保你的系统中使用的代码是经过审查的,并且软件的安装版本已经得到了开发人员和包维护人......
  • SpringBoot(三) - Slf4j+logback 日志,异步请求,定时任务
    1、Slf4j+logback日志SpringBoot框架的默认日志实现:slf4j+logback;默认日志级别:info,对应了实际生产环境日志级别;1.1日志级别#常见的日志框架中,日志级别都包含五种,......
  • Liunx中expect之交互式命令操作详解
    导航:一、expect安装、介绍、使用场景二、expect使用原理三、expect使用语法四、expect使用举例五、expect相关错误处理---------分割线----------一......
  • SpringMVC学习笔记
    13120171114......
  • spring注解笔记
    1122017102311220171023注意要点:配置Bean时刻注意IoC容器中Bean的数量以及类型,做到心中有底。[是自动装配还是主动配置要明确,不要重复注入]1、注解定义Bean1)、@Com......
  • 全网最全 Linux 命令总结
    今天,给小伙伴们带来一篇Linux命令总结非常全的文章,也是我们平时工作中使用率非常高的操作命令,命令有点多,建议小伙伴们可以先收藏后阅读。基本命令uname-m显示机器的处......
  • java方法详解
    一、何谓方法?System.out.println(),那么它是什么呢?Java方法是语句的集合,它们在一起执行一个功能。方法是解决一类问题的有序集合;方法包含于类或对象中;方法在程序......
  • 544JDBC各个类详解connection和545JDBC各个类详解_Statement
    详解个个对象1.OriverManager驱动管理对象上一个博客有讲解2.获取数据库连接上一个博客有讲解3.connection:数据库连接对象功能:1.获取执行sql的对象statement......
  • spring boot使用swagger生成api接口文档
    前言在之前的文章中,使用mybatis-plus生成了对应的包,在此基础上,我们针对项目的api接口,添加swagger配置和注解,生成swagger接口文档具体可以查看本站springboot系列文章:s......
  • SpringBoot 2.x 集成kaptcha生成图形验证码
    Kaptcha框架介绍谷歌开源的一个可高度配置的实用验证码生成工具验证码的字体/大小/颜色验证码内容的范围(数字,字母,中文汉字!)验证码图片的大小,边框,边框粗细,边框颜色......