Spring automatic assembly

This is the 14th day of my participation in the November Gwen Challenge. Check out the event details: The last Gwen Challenge 2021

Set injection and construct injection are sometimes cumbersome in configuration. Therefore, in order to improve the development efficiency, the framework provides automatic assembly function and simplifies configuration. The Spring framework does not support autowire by default. To use autowire, you need to modify the autowire attribute of the tag in the Spring configuration file

Let’s start with the scope of beans

The scope of the Bean

In Spring, the bodies that make up the application and the objects managed by the Spring IoC container are called beans. Simply put, beans are objects that are initialized, assembled, and managed by the IoC container.

Creating a bean definition is essentially a “recipe” for creating a real instance using the bean definition’s corresponding class. It makes sense to think of a bean definition as a recipe, much like a class, in that multiple instances can be created from a single “prescription.” You can control not only the various dependencies and configuration values injected into an object, but also the scope of that object. This gives you the flexibility to choose the scope of the object you build without having to define the scope at the Java Class level. The Spring Framework supports five scopes, described in the following table.

The Request and Session scopes are only used in Web-based applications (regardless of which Web application framework you are using), and only in web-based Spring ApplicationContext.

Singleton(Singleton pattern)

When a bean is scoped to a Singleton, there will be only one shared bean instance in the Spring IoC container, and all requests for the bean will return only the same instance of the bean as long as the ID matches the bean definition. A Singleton is a Singleton type that automatically creates a bean object when the container is created. It exists regardless of whether you use it or not, and the object you get is the same object each time. Note that the Singleton scope is the default scope in Spring. To define a bean as a singleton in XML, configure it as follows:

 <bean id="ServiceImpl" class="cn.csdn.service.ServiceImpl" scope="singleton">xml

Copy the code

Prototype

When a bean is scoped to Prototype, a bean definition corresponds to multiple object instances. A prototype-scoped bean results in a new bean instance being created each time the bean is requested (injected into another bean, or programmatically called on the container’s getBean() method). Prototype is the Prototype type, which is not instantiated when we create the container. Instead, we create an object when we get the bean, and we get a different object each time. As a rule of thumb, you should use the Prototype scope for stateful beans and the Singleton scope for stateless beans. Defining the bean as prototype in XML can be configured as follows:

<bean id="account" class="com.foo.DefaultAccount" scope="prototype"/>or<bean id="account" class="com.foo.DefaultAccount" singleton="false"/>
Copy the code

Request

When the scope of a bean is Request, it means that in an HTTP Request, one bean definition corresponds to one instance. That is, each HTTP request has its own bean instance, which is created from a bean definition. This scope is valid only in the case of web-based Spring ApplicationContext. Consider the following bean definition:

 <bean id="loginAction" class=cn.csdn.LoginAction" scope="request"/>
Copy the code

Session

When the scope of a bean is Session, it means that in an HTTP Session, one bean definition corresponds to one instance. This scope is valid only in the case of web-based Spring ApplicationContext. Consider the following bean definition:

 <bean id="userPreferences" class="com.foo.UserPreferences" scope="session"/>
Copy the code

For an HTTP Session, the Spring container creates a brand new userPreferences Bean instance based on the userPreferences Bean definition, And the userPreferences Bean is only valid for the current HTTP Session. As with the Request scope, you can safely change the internal state of the instance you create as needed, whereas other HTTP Session instances created under userPreferences will not see these session-specific state changes. When an HTTP Session is finally discarded, the beans scoped by that HTTP Session are also discarded.

Second, automatic assembly of beans

1.byName

byName

Autowire byName (automatic assembly byName)

If the Name of a bean is the same as the Name of a Property in another bean, the bean is automatically assembled into the Property. When a bean node has an autowire byName attribute, it looks for all the set method names in its class, gets the string with the set removed and lowercase, and then goes to the Spring container to find an object with the string name ID. If so, remove and inject; If not, a null pointer exception is reported.

During the manual configuration of XML, errors such as missing letters and case often occur and cannot be checked, which reduces the development efficiency.

Using autowiring will avoid these errors and simplify the configuration.

Testing:

Autowire = “byName”

<bean id="user" class="com.mq.pojo.User" autowire="byName">
   <property name="str" value="hahha"/>
</bean>
Copy the code

Summary:

When a bean node has the property Autowire byName.

  1. It looks for all set method names in its class, such as setCat, to get the string with the set removed and its initial lowercase, cat.
  2. Go to the Spring container and look for an object with the string name ID.
  3. If so, remove and inject; If not, a null pointer exception is reported.

2.byType

byType

Autowire byType (automatic assembly byType)

Using Autowire byType requires that objects of the same type are unique in the Spring container. If not, a unique exception is reported.

NoUniqueBeanDefinitionException
Copy the code

Testing:

Autowire = “byType”

<bean id="dog" class="com.mq.pojo.Dog"/>
<bean id="cat" class="com.mq.pojo.Cat"/>

<bean id="user" class="com.mq.pojo.User" autowire="byType">
   <property name="str" value="123456"/>
</bean>
Copy the code

Suppose we register another bean

<bean id="cat2" class="com.mq.pojo.Cat"/>
Copy the code

To use byType, you need to ensure that objects of the same type are unique in the Spring container. If they are not unique, they will raise unique exceptions. This assembly can be done without id, and ID light.

This is auto-assemble by type!

Three, use annotations to achieve automatic assembly

Use the annotation step

  1. Import constraints:
xmlns:context="http://www.springframework.org/schema/context"
Copy the code
  1. Configure annotation support

<context:annotation-config/>


      
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    <context:annotation-config/>

</beans>
Copy the code

Here are some common notes:

  1. @Autowired

The default value is ByName.

Can be used directly on a class property or in Set mode

With Autowired we can eliminate the need to write the Set method, provided that the autowiring property exists in the Ioc (Spring) container and conforms to the name byName!

@Nullable // The field marks the annotation, indicating that the field can be NULL
Copy the code
// If the required attribute value of Autowired is false, the object can be null, otherwise it cannot be null
public @interface Autowired {
    boolean required(a) default true;
}
Copy the code

@Qualifier(value=’ XXX ‘) can be used when the @Autowired autowage environment is complex and the autowage cannot be completed with a @autowired annotation

Use of @autoWired to specify the injection of a unique bean

    @Autowired
    @Qualifier(value = "add")
    private Address address;
Copy the code
  1. @Resource
    @Resource(name ="'name1'")
    private String name;
Copy the code

Summary:

The difference between @autowired and @Resource

  • Both are used for autowiring and can be placed on property fields
  • @autowired via byType and must require the object to exist
  • By default, @resource is implemented as byName. If the name is not found, bytype is implemented as bytype.
  • Different order of execution

4. Develop with annotations

To use annotation development after spring4, you need to ensure that the aop package is imported

Using annotations requires importing context constraints to add annotation support


      
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    <context:annotation-config/>

</beans>
Copy the code
  1. bean

    The @component Component is equivalent to

// @component is equivalent to 
      
@Component
public class User {
    private String name="Aiya!";
}
Copy the code
  1. How properties are injected

    @value (” oops “) =

// @component is equivalent to 
      
@Component
public class User {

   
      
    @ Value (" aiya! ")
    private String name;
}
Copy the code
  1. Derived note

@Component has several derived annotations, which we will layer in the MVC three-tier architecture for web development

  • The dao “@ Repository”
  • Service “@ service”
  • The controller “@ controller”

The four annotation functions are the same; they all represent registering a class to Spring and assembling the bean

  1. Automatically.
- @autoWired uses byType and must require the object to exist. - @nullable is used to mark the annotation, indicating that the field can be null. - @resource is implemented by default using byName. Bytype = bytype = bytype = bytypeCopy the code
  1. scope

@Scope(“prototype”)

// @component is equivalent to 
      
@Component
@Scope("prototype")
public class User {

   
      
    @ Value (" aiya! ")
    private String name;
}
Copy the code
  1. summary

XML with annotations

  • XML is more powerful, suitable for any situation, and easy to maintain
  • Annotations, not their own class can not use, maintenance is relatively complex

XML and annotation best practices

  • XML is used to manage beans
  • Annotations are responsible for completing the injection of attributes
  • There is only one problem we need to be aware of: to make annotations work, we need to turn on annotation support
<! -- Specify the package to scan, and the annotation under the package will take effect -->
    <context:component-scan base-package="com.mq.pojo"/>
    <context:annotation-config/>
Copy the code

Configure Spring using Java classes

We will now dispense with Spring’s XML configuration entirely and leave it to Java

JavaConfig is a subproject of Spring

The project structure

All the highlights and details are in the code’s annotations, look carefully.

Writing entity classes

package com.mq.pojo;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
// This annotation indicates that the class is registered by the Spring container
@Component
public class User {

    private String name;

    public String getName(a) {
        return name;
    }
    @Value("xiaoxiao")
    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString(a) {
        return "User{" +
                "name='" + name + '\' ' +
                '} '; }}Copy the code

The Java Config configuration file is equivalent to beans.xml

//@Configuration will also be hosted by the Spring container, registered with the container, because it is already an @Component
// @configuration means this is a Configuration class, just like beans.xml
 @Configuration
 @Import(Config2.class) // Import another configured Java class just as you imported another XML
public class Config {

    @Bean  The name of the method is the id in the bean label. The return value of the method is the class attribute of the bean label
    public User getuser(a){
        return new User();// Returns the object to be injected into the bean}}Copy the code

The test class

public class Mytext {

    public static void main(String[] args) {
        // If we do this completely, we'll have to get the container in the AnnotationConfig context, which is loaded by the AnnotationConfig class object
        ApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
        User getuser = (User) context.getBean("getuser"); System.out.println(getuser.getName()); }}Copy the code

Result: I added this annotation @value (“xiaoxiao”) to the entity class attribute so output this

That’s it for today’s share!