There are three ways for SpringBoot to introduce third-party jar beans

<img src="http://www.image.jincou.com/e6ad88b51f294ed580e3c5b4f4c1471b" width="700" height="234">

In the SpringBoot environment, the previous xml configuration bean is rarely used, mainly because it is not easy to maintain and convenient. Therefore, this blog post will not introduce the use of beans declared through xml in Spring.

1, Annotation assembly Bean

1. Use @ Component and other derived annotations

Just add the @ Component annotation on the class, and the annotation will be injected into the bean container of spring as long as it is scanned.

@Component
public class AnoDemoBean {
}

Of course, not only the @ Component annotation can declare beans, but also common annotations such as @ Repository, @ Service, @ Controller, etc.

If you look at these annotations, you will find that @ Component annotation is added to these annotations

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component   //You can see that @ Component is added to the @ Service annotation, as are @ Repository and @ Controller.        
public @interface Service {
    @AliasFor(
        annotation = Component.class
    )
    String value() default "";
}

The emergence of this series of annotations has brought us great convenience. We don't need to configure beans in the bean.xml file as before. Now we can easily define beans by adding relevant annotations to classes.

In fact, there is no special difference in the functions of these four annotations, but there is an unwritten agreement in the industry:

  • Controller is generally used in the control layer
  • Service is generally used in the business layer
  • Repository is generally used in the data layer
  • Component is generally used on common components

2. @ Bean definition method

In this way, beans are mainly defined in combination with Configuration. First, a Configuration class is declared, and then beans are declared in the Configuration class through the method form of returning bean objects. The following posture is usually used

@Data
public class ConfigDemoBean {
}

@Configuration
public class BeanLoadConfig {
    @Bean
    public ConfigDemoBean configDemoBean() {
        return new ConfigDemoBean();
    }
}

It should be noted that the BeanLoadConfig class itself is also regarded as a Bean by the Spring container.

3,@Component VS @Bean

1) The working objects are different: @ Component annotation works on classes, while @ Bean annotation works on methods.

This feature will make @ Bean more flexible. For example, when we reference a class in a third-party library and need to assemble it into the Spring container, we can only implement it through @ Bean.

such as

@Configuration
public class WireThirdLibClass {
    @Bean
    public ThirdLibClass getThirdLibClass() {
        //Third party ThirdLibClass class
        return new ThirdLibClass();
    }
}

Another example

@Bean
public OneService getService(status) {
    case (status)  {
        when 1:
                return new serviceImpl1();
        when 2:
                return new serviceImpl2();
        when 3:
                return new serviceImpl3();
    }
}

Both of these can not be achieved by @ Component, but can only be implemented by @ Bean, so @ Bean is more flexible.

2) @ Component is usually automatically assembled into the Spring container through classpath scanning. For @ bean, we usually define the logic to generate the bean in the annotated method.

We can add some @ Conditional,@ConditionalOnBean and other annotations to control whether to declare the Bean, which will not be automatically assembled into the Spring container at the beginning.

such as

public class MacCondition implements Condition {

   @Override
    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
        Environment environment = conditionContext.getEnvironment();
        String property = environment.getProperty("os.name");
        if (property.contains("Mac")) {
            log.info("The current operating system is: Mac OS X");
            return true;
        }
        return false;
    }
}



@Configuration
public class ConditionalConfig {
    /**
     * If the implementation method of MacCondition returns true, the bean is injected
     */
    @Bean("mac")
    @Conditional({MacCondition.class})
    public SystemBean systemMac() {
        log.info("ConditionalConfig Method injection mac entity");
        return new SystemBean("Mac ios system","001");
    }
}

The above example shows that if the current operating system is Mac, the current Bean will be injected. This can only be implemented with @ Bean annotation.

Summary: @ Component and @ Bean are both used to register beans and assemble them into the Spring container, but beans are more customizable than components. You can implement some custom loading classes that cannot be implemented by Component.


2, Bean importing external jar package

If the above annotation is added to the current project, when the springboot main class is started, the @ SpringBootApplication annotation will scan all classes to be assembled in this package and its sub packages by default and automatically assemble them into the spring bean container.

However, if you provide a jar package for third-party users, can the beans in your jar package be loaded by a third party?

It depends on the package name of your current project and the package name of the third-party Jar package you reference.

If the package address of your current project is com.jindou and the package of the third-party Jar you reference is com.third, that is, the Bean of the third-party Jar cannot be scanned, so it cannot be injected into the Spring container.

For example, there is a third-party Bean. What can I do to be scanned and injected into the Spring container.

package com.third.bean;

import org.springframework.stereotype.Component;

/**
 * @Description: This bean is used as a third-party bean for projects that depend on the jar package
 */
@Component
public class ThirdComponentBean {
    private String type = "Third party ThirdComponent Annotation generation bean entity";
}

1,@ComponentScan

It's very simple. Since the @ SpringBootApplication annotation scans only the current package and its sub packages by default, it's good to find a way to let it scan the packages of third-party jar s.

/**
 * @Description: Springboot Startup class
 */
@ComponentScan(basePackages ={"com.third.bean"})
@SpringBootApplication()
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class);
    }
}

@ComponentScan mainly defines the scanning path, finds out the classes that need to be assembled, and automatically assembles them into the bean container of spring.

The classes to be assembled are beans annotated with @ Controller, @ Service, @ Repository, @ Component, @ Configuration, etc. into the IOC container.

It is not necessary to add it to the startup class here. You can add it to the assembled class, but it is recommended to add it to the startup class, which is more intuitive. It is easier to find if you want to change or remove it later.

2. @ Import annotation

@ComponentScan scans the entire package, but in fact, you may only need to inject one or several specified beans, so we can consider using @ Import annotation

@Import(value= com.third.bean.ThirdComponentBean.class)
@SpringBootApplication()
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class);
    }
}

Doing so will also successfully inject the ThirdComponentBean object into Spring's bean container.

3,spring.factories

The above two injection methods have an obvious disadvantage, that is, if I need to reference the Bean of the external jar package, I need to configure @ ComponentScan or @ Import to scan in the current project to inject the current Bean, which is obviously not friendly.

Can the Bean of the third-party jar be directly referenced without doing anything in the current project?

Certainly.

We only need to put the configuration in the file specified by the third-party jar, and the user will load it automatically, so as to avoid code intrusion

  • Create a new directory META-INF under the resource directory
  • Create a new file spring.factories in the META-INF directory
  • Add the following configuration to the file
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.third.bean.ConfigurationBean

<img src="http://www.image.jincou.com/5a1be2b260604f3bbac69beae6eac318" width="400" height="250">

Complete project

The relevant demo projects have been put on gitHub. Here, two projects, create bean and third bean, are created. At the same time, the third bean is referenced by create bean as a third-party jar package, and relevant tests can be carried out on this demo.

GitHub project source code: https://github.com/yudiandemi...

This article is composed of blog one article multi posting platform OpenWrite release!

Tags: Java

Posted on Wed, 24 Nov 2021 23:54:56 -0500 by psych0