The application of Spring IOC in SpringBoot

Wikipedia description of the IOC:

As early as 2004, Martin Fowler asked, “Where has control been reversed? That’s the question. He concluded that the acquisition of dependent objects is reversed, because most applications have two or more classes cooperating with each other to implement business logic, making each object need to obtain a reference to the object it works with (that is, the object it depends on). If the retrieval process is self-contained, this results in highly coupled code that is difficult to maintain and debug.

A: on the Spring&SpringMVC & SpringBoot truedei.blog.csdn.net/article/det…

(I) Project preparation

To further my studies in this program, to learn about it through this program.

.com.shousidaima.truede.
					   -
                       -controller.
                         -HelloController.java
                       -dao.
                         -.impl.
                         	-HelloDaoJDBCImpl.java
                         -HelloDao.java
                       -entity.
                       	 -Hello.java
                       -service.
                       	 -HelloService.java
                         -impl.
    						-HeloServiceImpl.java
Copy the code

The details are as follows:

com.shousidaima.truede.HelloDao.java:

package com.shousidaima.truede.dao;


import com.shousidaima.truede.entity.Hello;

// Data access layer
public interface HelloDao {

    Hello getHello(int code,String msg);

}
Copy the code

com.shousidaima.truede.HelloJDBCImpl.java

We use Java classes to simulate JDBC linking; We usually use Mybatis to bind dao.

package com.shousidaima.truede.dao.Impl;

import com.shousidaima.truede.dao.HelloDao;
import com.shousidaima.truede.entity.Hello;
import org.springframework.stereotype.Repository;

@Repository
public class HelloJDBCImpl implements HelloDao {

    @Override
    public Hello getHello(int code, String msg) {
        Hello hello = new Hello();
        hello.setCode(code);
        hello.setMsg(msg);
        returnhello; }}Copy the code

com.shousidaima.truede.Hello.java

package com.shousidaima.truede.entity;

public class Hello {

    private String msg;

    private int code;

    public String getMsg(a) {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public int getCode(a) {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

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

com.shousidaima.truede.HelloService.java

package com.shousidaima.truede.service;

import com.shousidaima.truede.entity.Hello;



public interface HelloService {

    Hello getHello(int code, String msg);

}
Copy the code

com.shousidaima.truede.HelloServiceImpl.java

package com.shousidaima.truede.service.impl;

import com.shousidaima.truede.dao.HelloDao;
import com.shousidaima.truede.entity.Hello;
import com.shousidaima.truede.service.HelloService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


@Service
public class HelloServiceImpl implements HelloService {

    @Autowired
    HelloDao helloDao;

    @Override
    public Hello getHello(int code, String msg) {
        returnhelloDao.getHello(code,msg); }}Copy the code

(2) Write test unit & validation

package com.shousidaima.truede;

import com.shousidaima.truede.entity.Hello;
import com.shousidaima.truede.service.HelloService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class TruedeApplicationTests {

	@Autowired
	HelloService helloService;

	@Test
	void contextLoads(a) {
		Hello hello = helloService.getHello(200."Visit successful!"); System.out.println(hello); }}Copy the code

After starting the test unit:

(3) Analyze which objects are managed by BeanFactory?

@Repository
public class HelloJDBCImpl implements HelloDao {}@Service
public class HelloServiceImpl implements HelloService {}Copy the code

You can see that both classes have annotations in their headers, @repository and @service.

@repository: code that identifies this class as a data access layer; @service: identifies this class as business layer code;

In fact, there is no essential difference between the two, the code is the same, only the annotation name is different:

The purpose of doing this is also to distinguish for the class what type of class object your class is.

The point is that both classes have the @Component annotation, which is one of the ways Spring uses to inject Bena.

Back to the HelloController.java object:

@Controller
@RequestMapping(value = "hello")
public class HelloController {

    @RequestMapping(value = "getHello",method = RequestMethod.GET)
    @ResponseBody
    public String getHello(a){
        return "HelloController hello."; }}Copy the code

The source code for the @Controller annotation is as follows:

Surprisingly, the source code for @Repository and @Service is the same as the source code for @Repository and @Service, again to identify what type this class is. Adding @Controller indicates that this is a Java class at the control layer, so when accessed, the object is accessed (and, of course, processed).

(4) Why is entity class not managed by BeanFactory?

Because an entity class can be created and used many times in a project, the data will be different and there is no need to be managed by the BeanFactory.

(5) Which entity classes should be managed?

Singletons should be managed: (1) unified resource classes; (2) Use the same object N times;

In Spring, or SpringBoot, or Mybatis, or some spring-related open source framework, IOC (dependency injection, also known as BeanFactory managed objects) is basically a must.

(1) For example, we set server.port=8081

The parameters actually passed are received by the ServerProperties.java file and managed. When SpringBoot is started, it takes the serverProperties.java parameter port.

Serverproperties.java source code is as follows:

@ConfigurationProperties( prefix = "server", ignoreUnknownFields = true )
public class ServerProperties {
    private Integer port;
    privateInetAddress address; . }Copy the code

(2) For example: configuration file data in a framework I open source is hosted this way

It is convenient to configure some information using a configuration file.

Most open source frameworks are used in the framework I develop.

My unified entry: swaggerPluginconfig.java a piece of code

/** * Spring IOC unified management object */
@Configuration
public class SwaggerPluginConfig {

	// Get the information at the beginning of swagger-plugin from the configuration file
    @ConfigurationProperties(prefix = "swagger-plugin")
    @Bean(name = "swaggerPluginConfigBean")
    public SwaggerPluginConfigBean getSwaggerPluginConfigBean(a){
        return newSwaggerPluginConfigBean(); }}Copy the code

So the project using my framework needs to be in the configuration file (application.yml) :

# swagger configuration
swagger-plugin:
    Configure the Controller layer to scan
    scan:
        path: com.springbootswagger1.controller
    Whether to enable the debug mode of swagger-Plugin framework
    debug: true
Copy the code

So I can get it directly in the framework:

  @Autowired
  private SwaggerPluginConfigBean swaggerPluginConfigBean;
Copy the code

Call directly when using:

try{... }catch (CannotCompileException e) {
    If the debug mode is enabled, the log will be printed
    if(swaggerPluginConfigBean.isDebug()){
        logger.warn("Can't find 1:"+e.getMessage()); }}catch (NotFoundException e) {
    if(swaggerPluginConfigBean.isDebug()){
        logger.warn("Can't find 2:"+e.getMessage()); }}Copy the code

That is the benefit of the IOC.

(6) Obtain Spring IOC-managed beans

package com.shousidaima.truede;

import com.shousidaima.truede.entity.Hello;
import com.shousidaima.truede.service.HelloService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationContextFactory;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.web.context.WebApplicationContext;

@SpringBootTest
class TruedeApplicationTests implements ApplicationContextAware {

	@Autowired
	HelloService helloService;

	@Test
	void contextLoads(a) {
		Hello hello = helloService.getHello(200."Visit successful!");
		System.out.println(hello);
	}

	private  ApplicationContext applicationContext;

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {

		if (this.applicationContext == null) {
			this.applicationContext = applicationContext; }}@Test
	public void testGetBean(a){
		HelloService bean = applicationContext.getBean(HelloService.class);
		System.out.println(bean.getHello(100."Hello?")); }}Copy the code

When we execute the testGetBean() test unit, we print:

Hello{msg='Hello', code=100}
Copy the code

So it’s valid.

It can also be set according to different requirements

@Test
public void testGetBean(a){
    // From the class of the specific class
    HelloService bean = applicationContext.getBean(HelloService.class);
    System.out.println(bean.getHello(100."Hello?"));

    // Obtain by name +class
    HelloService helloService = applicationContext.getBean("helloServiceImpl", HelloService.class);
    System.out.println(helloService.getHello(1022."Ha ha ha."));

    // Get by name
    // The default name is regular: Java name: HelloServiceImpl -->bean name: HelloServiceImpl
    HelloService helloService1 = (HelloService) applicationContext.getBean("helloServiceImpl");
    System.out.println(helloService.getHello(Awesome!."66666"));

}
Copy the code

Results:

Hello{msg='Hello', code=100}
Hello{msg='Hahaha', code=1022}
Hello{msg='66666', code=Awesome!}
Copy the code

You can also specify the bean name, which varies depending on the injection method

For example, the business implementation layer:

Just specify the name in the @service annotation

@Service("helloimpl")
public class HelloServiceImpl implements HelloService {... }Copy the code

So when you get:

@Test
public void test1(a){
    HelloService helloimpl = applicationContext.getBean("helloimpl", HelloService.class);
    System.out.println(helloimpl.getHello(10086."hhhhh"));
}
Copy the code

The use of Spring AOP in SpringBoot

In order to give readers a better reading experience, hereby separate to write, pay attention to me, see the next article.

Principles of Spring IoC

In order to give readers a better reading experience, hereby separate to write, pay attention to me, see the next article.

The principles of Spring AOP

In order to give readers a better reading experience, hereby separate to write, pay attention to me, see the next article.