Configuration and use of Bean annotations

This knowledge should be learned in Spring, did not learn or forgotten friends need to preview or review the knowledge. SpringBoot is actually a further simplification of Spring, so it is necessary to learn the pre-knowledge points, so that we can understand the underlying principles.

All right, without further ado, let’s go!

Structure directory:

pojo–User:

package com.xbhog.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@NoArgsConstructor
@AllArgsConstructor
@Data
public class User {
    private  String name;
    private int age;
}

Copy the code

config-MyConfig:

package com.xbhog.config;

import com.xbhog.pojo.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MyConfig {
    @Bean
    public User user(a){
        return new User("xbhog".18); }}Copy the code

controller-Mycontroller:

package com.xbhog.controller;

import com.xbhog.config.MyConfig;
import com.xbhog.pojo.User;
import org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Mycontroller {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
        User user = context.getBean("user", User.class); System.out.println(user.toString()); }}Copy the code

The first three files are buried in a hole where the beans will not be found by SpringBoot, because we must place the files in the same directory as the main launcher in order to find them, as follows: This is due to the scan path of SpringBootApplication

But when we put Myapp into the main application folder: we found that the corresponding component information was not found

In the case of not changing the original program, we can use manual scanning and set a custom scanning path:

package com.xbhog.springboot1times;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ComponentScan;

//@SpringBootApplication
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan("com.xbhog")   // Set the scan path
public class Myapp {
    public static void main(String[] args) {
        Return our IOC container */
        ConfigurableApplicationContext run = SpringApplication.run(Myapp.class, args);
        /*2. View the components in the container */
        String[] names = run.getBeanDefinitionNames();
        for(String name:names){ System.out.println(name); }}}Copy the code

Effect display:

Single instance problem:

  1. Determine whether a component is a single instance in the container:
package com.xbhog.springboot1times;

import com.xbhog.pojo.Pet;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ComponentScan;

//@SpringBootApplication
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan("com.xbhog")
public class Myapp {
    public static void main(String[] args) {
        Return our IOC container */
        ConfigurableApplicationContext run = SpringApplication.run(Myapp.class, args);
        /*2. Get the component */ from the container
        Pet tom1 = run.getBean("tom11", Pet.class);
        Pet tom2 = run.getBean("tom11", Pet.class);
        System.out.println("Is the component a single instance?"+(tom1== tom2)); }}Copy the code

Whether the component is single instance: true

Myconfig call problem:

Since a configuration class is also a component, if we get a configuration class component and invoke its bean by instantiating an object, do we call a normal method or the corresponding component in the container?

package com.xbhog.springboot1times;

import com.xbhog.config.MyConfig;
import com.xbhog.pojo.Pet;
import com.xbhog.pojo.User;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ComponentScan;

//@SpringBootApplication
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan("com.xbhog")
public class Myapp {
    public static void main(String[] args) {
        Return our IOC container */
        ConfigurableApplicationContext run = SpringApplication.run(Myapp.class, args);
        /*2. View the components in the container */
        String[] names = run.getBeanDefinitionNames();
        for(String name:names){
            System.out.println(name);
        }
        /*3. Get the component */ from the container
        Pet tom1 = run.getBean("tom11", Pet.class);
        Pet tom2 = run.getBean("tom11", Pet.class);
        System.out.println("Is the component a single instance?"+(tom1== tom2));

        MyConfig bean = run.getBean(MyConfig.class);
        System.out.println(bean);

        User user1 = bean.user();
        User user2 = bean.user();
        System.out.println("Test the User component called through the Myconfig class:"+(user1==user2)); }}Copy the code

The effect is as follows:

Whether components for single instance: true com xbhog. Config. MyConfig EnhancerBySpringCGLIB 9 b1ae7c2 @ 6 c0905f6 test by MyConfig class called user components: trueCopy the code

This is the effect of Configuration(proxyBeanMethods=true) to ensure that each @bean method is called how many times the returned component is a single instance

ProxyBeanMethods: proxyBeanMethods: proxyBeanMethods: proxyBeanMethods: proxyBeanMethods: proxyBeanMethods: proxyBeanMethods: proxyBeanMethods: proxyBeanMethods: proxyBeanMethods: proxyBeanMethods: proxyBeanMethods: proxyBeanMethods (true);

When proxyBeanMethods = true:

The Bean returned by MyConfig is itself a proxy object, CGLIB, and tests the User component called through the MyConfig class: true.

com.xbhog.config.MyConfig EnhancerBySpringCGLIB 9b1ae7c2@6c0905f6

MyConfig bean = run.getBean(MyConfig.class);
System.out.println(bean);
// If @configuration (proxyBeanMethods = true) the proxy object calls the method.
// SpringBoot always checks to see if this component is present in the container.
User user1 = bean.user();
User user2 = bean.user();
System.out.println("Test the User component called through the Myconfig class:"+(user1==user2));
Copy the code

When: proxyBeanMethods=false (Lite mode) :

MyCnfig will not return proxy mode and test the User component called through Myconfig class: false

Conclusion:

ProxyBeanMethods: proxyBeanMethods;

  • Full(proxyBeanMethods = true)
  • Lite(proxyBeanMethods = false)
  • Component dependencies must be in Full mode by default. Others Lite mode or not by default

Usage scenario:

Now add the Pet object to pojo.user:

package com.xbhog.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@NoArgsConstructor
@AllArgsConstructor
@Data
public class User {
    private  String name;
    private int age;
    private  Pet pet;
}
Copy the code

(proxyBeanMethods=true)

package com.xbhog.config;

import com.xbhog.pojo.Pet;
import com.xbhog.pojo.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration  // Tell SpringBoot that this is a configuration class == application.xml
public class MyConfig {
    @Bean  // Add a component to the container with the name of the component as its ID and the return type being the component type. The value returned is the instance of the component in the container
    public User user(a){
        User user = new User("xbhog".18);
        // The user component depends on the Pet component. The Pet in the user is the same as the Pet in the container
        user.setPet(tomcat());
        return user;
    }
    @Bean("tom11")  // Set the bean alias -- the name of the bean ID
    public Pet tomcat(a){
        return new Pet("tomcat"); }}Copy the code
User user = run.getBean("user", User.class);
Pet tom3 = run.getBean("tom11", Pet.class);
System.out.println("User's pet"+(user.getPet() == tom3));
Copy the code

User’s pet true;

After proxyBeanMethods=false mode, create an object without scanning the container:

Whether the component is the single instance: true com. Xbhog. Config. MyConfig @ 330 c1f61 test through MyConfig class calls the user module: false false user pet

If you see here or just to help you, I hope you can point to follow or recommend, thank you; If there are any errors, please point them out in the comments and the author sees them will be corrected.