==============================
The name of the Bean in the Spring container
==============================
There are two ways to declare a bean, one is @Bean, the other is @Component and its subclasses (including @Service/@Controller/@Repository/@Configuration), and the bean name in the Spring container generates a rule There are two major categories, namely:
I. @Component and its sub-annotations are used to annotate Class. The naming conventions for these annotation label beans are:
1. If the parameter value is specified @Component, the value of the parameter is the bean name.
2. If the @Component does not specify a parameter value, the bean name depends on the class name being annotated, if the class name starts with two or two uppercase letters, the bean name is identical to the same name; If there is only one uppercase letter at the beginning, the bean name is the first lowercase version of the class name.
Two. @Bean annotations are often used to label a function, @Bean the naming rules for annotation label beans are:
1. If the name parameter is specified @Bean, the parameter will prevail.
2. Without specifying the name parameter, use the method name as the name of the bean.
==============================
Bean Scope
==============================
Reference: Https://www.jianshu.com/p/502c40cc1c41
Beans are commonly used in the following 5 categories,
@Scope ("singleton")
@Scope ("prototype")
@Scope ("Request")
@Scope ("session")
@Scope ("Global-session")
1. The bean labeled @Scope ("singleton") indicates that only one instance of the bean is created in the Spring container, and the bean instantiation is normally done when the application starts. The same instance is used each time the bean is called during the execution of the program. This is also the default scope for Spring.
2. The bean labeled @Scope ("Prototype") creates a new instance each time it gets the bean.
3. @Scope ("request"), for WEB projects only, create a new Bean instance for each HTTP request.
4. @Scope ("session"), which applies only to WEB projects, creates a new Bean instance for each HTTP session.
5. @Scope ("Global-session"), for the portal Web project only, create a new Bean instance for each global HTTP session.
The singleton Bean is initialized after the container is created, essentially the same as when a JVM is started and a bean instance is created, and if the application is concerned about startup time, you can add a @Lazy annotation when declaring the bean, and the bean instantiation will be deferred until the first fetch is An object. In general, it is strongly recommended that all Singleton beans do not enable lazy loading so that problems can be found when the program is started.
==============================
Thread safety issues for different scope beans
==============================
Spring's default scope is singleton, because it does not require frequent object creation and memory reclamation, but it has the best performance, but requires attention to thread safety issues.
Prototype type of bean, each injection is a completely new object, apparently there is no thread safety problem.
The request and Session object, unless we use multithreading in the same request or session, need to be aware of the thread-safety issue, in the vast majority of cases, these two scope-type beans are thread-safe, and because the bean is a form- Convenient for web application development.
For singleton types of beans, how do you do thread safety? There are generally two methods:
1. The Bean class does not define member variables at all, thus eliminating the risk of thread insecurity.
2. If the Bean class must have member variables, be sure to add the member variable to ThreadLocal.
Or, simply change the singleton scope to prototype.
==============================
Initialization hooks for Bean objects
==============================
Consider the following scenario:
1. We need to inject a bean object and make some special settings for the Bean object, and this Bean object class code does not belong to our tube.
2. For Boss This object, inject many kinds of bean objects (such as Car/office, etc.), how to set up a special set of Car/office objects in one code?
Obviously these scenarios cannot be implemented by the constructor of the Bean class, which we can implement in the following two ways in the Spring project:
1. The @Bean annotations provided by Spring have Initmethod and Destroymethod properties.
2. The criteria defined by JSR-250 are @PostConstruct as well as @PreDestroy annotations, which are generally used in conjunction with @Component.
==============================
@Autowired Bean Injection
==============================
@Autowired can annotate the class member variables, methods, and constructors to complete the automatic assembly task.
1. You can omit the setter method by labeling the class member variable.
Public class Boss { @Autowired private car car;}
2. On the class's method, Spring automatically completes the "All Bean" argument assembly.
Public class Boss { private car car; Private Office Office; @Autowired publicvoid Init (car car, office Office) { this . Car = car; this. Office = Office; }}
3. On the class's constructor, Spring automatically completes the "All Bean" argument assembly.
Public class Boss { private car car; Private Office Office; @Autowired public Boss (car car, office Office) { this. Car= car; this. Office = Office; }}
4. @Autowired the meaning of the annotation on the collection or on the array: it is used to get multiple implementations of the same interface.
Excerpted from Https://www.chkui.com/article/spring/spring_core_auto_inject_of_annotation
Interface A {} @Component class Implements a{} @Component class Implements a{} class MyClass { @Autowired private a[] A; @Autowired private set<a> Set; @Autowired private map<string, a> Map;}
When using MAP, key must be declared as a String and at run time Key is the name/id of the injected Bean.
==============================
Bean Injection of jsr-250/jsr-330
==============================
The injection annotations of the JSR-250 standard are @Resource.
The injection annotations of the JSR-330 standard are @Inject.
Spring's proprietary injection annotations are @Autowired.
@Inject annotations are almost the same as @Autowired, which is less functional than @Autowired (for example, there is no required attribute), so it is not recommended.
In actual projects, @Autowired and @Resource are often used.
The @Autowired by default is Bytype injected, and the @Resource itself has the name and type attributes, which by default are injected by ByName.
The execution path of the @Autowired and @Inject injected Bean object is:
1.Match by Type: priority Bytype Injection
2.Restricts by Qualifier: injected according to the name specified by the @Qualifier, but if not injected successfully, direct error.
3.Match by name: Finally, follow the default Name injection.
The execution path of the @Resource injected Bean object is:
1. If both name and type are specified, an assembly is found in the container for the bean with the name and type matching, and an exception is thrown if it is not found.
2. If name is specified, a bean matching the name (ID) in the container is assembled and an exception is thrown if it is not found.
3. If type is specified, an exception is thrown when a unique bean of type matching is found in the container to be assembled, not found, or more than one is found.
4. If neither name is specified and type is not specified, the following execution path is followed:
4.1 is injected by default name.
4.2 Injected by type.
4.3 is injected according to @Qualifier modification.
Reference:
http://javainsimpleway.com/autowired-resource-and-inject-2/
Http://einverne.github.io/post/2017/08/autowired-vs-resource-vs-inject.html
==============================
@Primary resolving multiple subclasses cannot inject problems
==============================
Sometimes in our project, there may be multiple implementations (or subclasses) of the same interface, and an error occurs when the bean instance is injected using a @Autowired. The reason is simple, @Autowired injected by type by default, there are now multiple subclasses, and the Spring IoC container does not know how to inject it.
Solution style when declaring a Bean, you can add another @Primary annotation. @Primary can be used in combination with @Component or with @Bean.
@Component @primary Public classBenzcarImplementsICar { Public voidrun () {System.out.println ("Benz Run"); } @Override PublicString toString () {return"Brand:benz, price:1000"; }} @Component Public classVwcarImplementsICar { Public voidrun () {System.out.println ("VW Run"); } @Override PublicString toString () {return"Brand:volkwargon, price:1000"; }} @Component Public classBoss {@AutowiredPrivateICar Car;} @Configuration @componentscan ("Javatestmaven.demo2") Public classSomeconfig {} Public classApp { Public Static voidMain (string[] args) {app app=NewApp (); Annotationconfigapplicationcontext Context=NewAnnotationconfigapplicationcontext (); Context.register (someconfig.class); Context.refresh (); Boss Boss= Context.getbean (Boss.class); SYSTEM.OUT.PRINTLN (boss); Context.close (); }}
==============================
Use of @Qualifier
==============================
In the previous example, @Primary annotations were used to solve situations where multiple subclasses could not be injected, but Spring also provides other options, @Qualifier annotations are one of them.
Once the @Qualifier is added, the @Autowired will be injected with the parameters set by the @Qualifier after the Bytype injection fails. @Qualifier can be used with @Autowired/@Resource/@Inject, but in most cases it is used in conjunction with @Autowired.
The callout object @Autowired is a member variable, method, constructor.
The callout object @Qualifier is a member variable, a method entry parameter, and a constructor entry.
The above statement seems to be the same, in fact, there is a difference, the focus is two annotation modification of the subject is different, in the annotated method, for example, @Qualifier decorated with a single argument, and @Autowired modified is the method body. If the method has multiple form parameters for a bean class, each parameter can be @Qualifier decorated.
The following is an example @Qualifier used to construct parameter arguments.
Public class Boss { private car car; Private Office Office; @Autowired public Boss (car car , @Qualifier ("Office") office Office) { this. Car = car; this. Office = Office; }}
==============================
@Conditional Implementing Conditional injection
==============================
@Primary disadvantage: By typing the interface and a specific implementation of the binding dead, the benefit: we can switch Primary class at any time, to achieve the implementation of switching.
@Qualifier disadvantage: By the name of the interface and the implementation of the name of the binding dead, the benefit: We can adjust the name at any time to achieve the implementation of the switch.
But in general @Primary and @Qualifier are a bit hard code taste, what better solution? The answer is @Conditional, which is slightly more complex to use, and the Spring Boot uses a lot of @Conditional annotations, such as a multi-profile environment.
First we need to implement the Spring Condition interface, and then declare the Bean type using the @Conditional + @Bean combination in the Config class. After adding @Conditional, you will determine which subclass to use when the bean is instantiated by the actual condition evaluate.
Public classLinuxconditionImplementsCondition { Public Booleanmatches (conditioncontext context, Annotatedtypemetadata metadata) {BooleanResult=context.getenvironment (). GetProperty ("Os.name"). Contains ("Linux"); returnresult; }} Public classWindowsconditionImplementsCondition { Public Booleanmatches (conditioncontext context, Annotatedtypemetadata metadata) {BooleanResult=context.getenvironment (). GetProperty ("Os.name"). Contains ("Windows"); returnresult; }} @Configuration @componentscan ("Javatestmaven.demo2") Public classsomeconfig {@Bean @Conditional (linuxcondition.class) PublicICar Getbenzvwcar () {return NewVwcar (); } @Bean @Conditional (windowscondition.class) PublicICar Getbenzcar () {return NewBenzcar (); }} Public classApp { Public Static voidMain (string[] args) {app app=NewApp (); Annotationconfigapplicationcontext Context=NewAnnotationconfigapplicationcontext (); Context.register (someconfig.class); Context.refresh (); ICar Car= Context.getbean (ICar.class); SYSTEM.OUT.PRINTLN (car); Context.close (); }}
==============================
Other notes for Spring
==============================
I. @Autowired (REQUIRED=FALSE)
@Autowired () If you do not specify the required property, the equivalent of the Required property is true, meaning that the injected object cannot be null, and if Required=false is set, the injected object can be null.
Because the @Autowired (Required=false) allows nulls to be injected, it poses a potential problem for the program, so it is only used during the development and testing phases, such as a dependent class that has not been declared as a bean.
Two. @Required
Dependency injection is primarily two ways, either by constructing a sub-injection or by injecting through a setter function, in general we will inject the necessary dependencies through the constructor, and for non-essential dependencies through the setter function.
Spring provides @Required annotations that can raise a Setter to the required level.
The @Required is used to annotate setter methods, only for setter injection based on XML configuration, and the effect is the same as @Autowired (Required=true), which is recommended for use.
Three. @DependsOn
Direct dependencies are recommended using the constructor and Setter function settings, but you can use @DependsOn for objects or dependencies that are not directly dependent.
Four. @Order
@Order is generally used in order to instantiate bean objects that control multiple subclasses, the smaller the parameter values of the @Order () annotations, the sooner the instantiation.
In the example below, the first element in LST is the ImplA2 object, and the second element is the ImplA1 object.
interface A {} @Component @order ( 2 Span style= "color: #000000;" >) class implA1 implements a{} @Component @order ( 1 class implA2 implements a{} class MyClass {@Autowired private
list<a> lst;}
===============================
Reference
===============================
Https://www.chkui.com/article/spring/spring_core_auto_inject_of_annotation
https://www.ibm.com/developerworks/cn/java/j-lo-spring25-ioc/
Https://www.ibm.com/developerworks/cn/java/j-lo-spring25-mvc/
Https://www.baeldung.com/spring-autowire
Springboot Series: Understanding Spring's Dependency Injection (ii)