current position:Home>Spring common annotation analysis

Spring common annotation analysis

2022-08-06 17:33:28ytKing

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第5天,点击查看活动详情

Spring注解分析

[email protected]

普通字符串

//Directly assigns the current string to the current field
@value(“xxx”)
复制代码

占位符

//先进行占位符的替换,Then assign the replaced string to the current field
//According to the operating system environment variables、jvm环境变量、ymlfiles, etc. as alternative sources
@value("$xxx")
复制代码

SpringEL

Spring 表达式语言 (SpEL)

//先解析Spring表达式,将结果赋值给当前字段
//注意:The result of parsing the expression may be a string,也有可能是一个bean对象
@value("#{xxx}")
复制代码

基于@value的扩展

image-20220628093008364

[email protected]

Spring的@Bean注解用于告诉方法,产生一个Bean对象,然后这个Bean对象交给Spring管理. 产生这个Bean对象的方法Spring只会调用一次,随后这个Spring将会将这个Bean对象放在自己的IOC容器中[email protected]明确地指示了一种方法,什么方法呢?产生一个bean的方法,并且交给Spring容器管理;从这我们就明白了为啥@Bean是放在方法的注释上了,因为它很明确地告诉被注释的方法,你给我产生一个Bean,然后交给Spring容器,剩下的你就别管了.记住,@Bean就放在方法上,就是让方法去产生一个Bean,然后交给Spring容器.@Component , @Repository , @ Controller , @Service 这些注解只局限于自己编写的类,而@Bean注解能把第三方库中的类实例加入IOC容器中并交给spring管理[email protected]注解的另一个好处就是能够动态获取一个Bean对象,能够根据环境不同得到不同的Bean对象.

@Bean是否要跟@Configuration配合使用

结论:@Bean + @Component,虽然@BeanThe instance returned by the annotated method has been injected into itSpringIOC容器中,但是每次调用@Bean注解的方法时,A new object instance is createdbean返回,并不会从IOC容器中获取.

因此,要实现在@Bean注解方法时,要求从IOCInstances are returned in the containerbeanInstead of creating a new object every time,则@Bean要跟@Configuration配合使用
复制代码

tips:@Bean的autowiredThe parameter has been deprecated,Because of this property it is possible to convert thisbeanThe properties inside are injected as required,但是没有@AutowiredAnnotations are so flexible,@Autowired加在beanWhich property is injected into it,但是autowiredAll parameters are injected,不够灵活,所以默认是不开启的(NO).

image-20220628211438488

[email protected]

@ComponentScan主要就是定义扫描的路径从中找出标识了需要装配的类自动装配到spring的bean容器中,主要作用是:

用于完成组件扫描,指定 spring 扫描范围,通过它指定的路径,Spring 会从被指定的包及其下级包扫描 @Component 及其子类注释的类,用于 Spring 容器自动装配,也就是告诉 Spring 从哪里找到 bean.

不过需要注意,其仅仅是指定了要扫描的包,并没有装配其中的类,这个真正装配这些类是 @EnableAutoConfiguration 完成的.

includeFilters(包含规则)&excludeFilters(排除规则)

image-20220629222200475

FilterType为一个枚举类,总共有5个值,也就是说type总共有5个可选值

public enum FilterType {
	ANNOTATION,//按照注解方式
	ASSIGNABLE_TYPE,//according to the specified type
	ASPECTJ,//使用ASPECTJ表达式的方式
	REGEX,//Specify using regular expressions
	CUSTOM//自己实现TypeFilterInterface for custom rules(如下面的代码)
}
//示例:
// includeFilters 用法 包含Animal.classClasses can be scanned,包括其子类
@ComponentScan(value = "com.spring" includeFilters = {@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {Animal.class} )} )

// excludeFilters 用法 排除包含@Controller注解的类
@ComponentScan(value = "com.spring" , excludeFilters = { @ComponentScan.Filter(type = FilterType.ANNOTATION , classes = {Controller.class} ), })
复制代码

扫描索引

META-INF/spring.factories文件的作用是什么

[email protected]

image-20220701145640072

一文了解@Conditional注解说明和使用

[email protected]

在属性上使用*@Autowired*

@AutowiredCan be applied directly to the properties of the class,Even if the property's type is notpublic、It is also not definedsetter方法,Nor does it affect the functionality of autowiring.Spring在创建Bean的过程中,会根据字段的类型和名字从Springfound in the container that matchesBean对象进行赋值.

在setter方法上使用*@Autowired*

and use on properties*@Autowiredto complete the autowiring comparison,在setter上使用@Autowired*There is no obvious no 同.When we want to perform some logical operation while assembling a property,tend to do so.Spring会Find the matched one from the container according to the input parameter informationBeanThe object is passed to the input parameter,通过set方法中给属性赋值,从而达到了set注入的目的,It is this annotation that needs attentionIt can also be added to the normal method上,不一定非得是set方法.

在构造函数上使用*@Autowired*

When used on a construction parameter*@Autowired* 时表示该BeanThis constructor is used to instantiate an object at creation time,并且SpringThe type and name of the parameters are passed in according to the constructor,从Springfound in the container that matchesBeanThe object is passed to the input parameter for assignment,So as to achieve the purpose of constructor injection.值得注意的是,在较新的SpringThe version declared on the constructor can be completely omitted*@Autowired*注解,但是Limited to only one constructor的情况下,If there are multiple constructors with parameters required添加@Autowired注解指定构造方法.

NoSuchBeanDefinitionException

NoSuchBeanDefinitionException直译为:没有找到相关的bean.根据实际情况不同,There are two ways to resolve this exception:

  • The first is a mistake that we are prone to make in the early stage,i.e. we do need such onebean,而且该beanAlso provided by us,但忘记使用*@Component* Relevant clarifications have been made.The solution, of course, is to declare the typebean即可.

  • The second is thebean可以有,也可以没有.Then you can now*@Autowired* 的required 属性设置为false :

    @Service
    public class BarService {
        @Autowired(required = false)
        BarRepository barRepository;
    }
    复制代码

NoUniqueBeanDefinitionException

默认情况下@Autowired注解是根据类型to complete the automatic assembly,During the assembly process if the same typebean存在多个,则会发生NoUniqueBeanDefinitionException异常.

Custom assembly qualifiers

SpringAlso allows us [email protected] on other notes,Makes the annotation also [email protected] related functions.

static

static字段或方法是不会进行依赖注入的.

为什么SpringTeam referrals are always yoursbean中使用构造函数建立依赖注入?

image-20220702143255662

@Autowired 可以对成员变量、方法(一般是set方法,Of course other methods are also possible)以及构造方法三种方式操作(It can also be added in front of parameters,不过没什么用,And add custom annotations on top of other annotations)[email protected]注入bean,相当于在配置文件中配置bean.And for the construction method,It is equivalent to using the constructor for dependency injection.通过一个例子说明**@Autowiredand constructor execution order difference**:

image-20220702144327923

Java变量的初始化顺序:静态变量或静态语句块–>实例变量或初始化语句块–>构造方法–>@Autowired

因此能够保证注入的组件不可变,并且确保需要的依赖不为空.此外,构造器注入的依赖总是能够在返回客户端(组件)代码的时候保证完全初始化的状态.

  • 依赖不可变:其实说的就是final关键字.
  • 依赖不为空(省去了我们对其检查):当要实例化UserServiceImpl的时候,由于自己实现了有参数的构造函数,所以不会调用默认构造函数,那么就需要Spring容器传入所需要的参数,所以就两种情况:1、有该类型的参数->传入,OK .2:无该类型的参数->报错.
  • 完全初始化的状态:这个可以跟上面的依赖不为空结合起来,向构造器传参之前,要确保注入的内容不为空,那么肯定要调用依赖组件的构造方法完成实例化.而在Java类加载实例化的过程中,构造方法是最后一步(之前如果有父类先初始化父类,然后自己的成员变量,最后才是构造方法),所以返回来的都是初始化之后的状态.
补充:为什么要加final?
网上解释:

1.spring配置默认的bean的scope是singleton,也就是启动后一直有.通过设置bean的scope属性为prototype来声明该对象为动态创建.但是,如果你的service本身是singleton,注入只执行一次.@Autowired本身就是单例模式,只会在程序启动时执行一次,即使不定义final也不会初始化第二次,所以这个final是没有意义的吧.可能是为了防止,在程序运行的时候,又执行了一遍构造函数

2.或者是更容易让人理解的意思,加上final只会在程序启动的时候初始化一次,并且在程序运行的时候不会再改变.
复制代码

[email protected]

image-20220702155412998

[email protected]

image-20220702161759857

[email protected]

image-20220703102211365

当proxyBeanMethods为true时(默认为true),Call configuration class component creationbean的方法,获得的beanis obtained directly from the container,而为false时,is to recreate.这其实是springbootThe bottom two modesFull模式和Lite模式,当我们配置 Used when there are no dependencies between class componentsLite模式加速容器启动过程,减少判断,配置类组件之间有依赖关系,方法会被调用得到之前单实例组件,用Full模式.

[email protected]

spring注解之@Import注解的三种使用方式

copyright notice
author[ytKing],Please bring the original link to reprint, thank you.
https://en.cdmana.com/2022/218/202208061702145016.html

Random recommended