Spring and Spring Boot related knowledge collation

1. Mind map

Insert picture description here

Note: The use of @Configuration to declare a bean in the java code-instead of using xml-actually existed very early (at least when "Spring Actual Combat (3rd Edition)" was published, that is, when Spring 3.0), I always thought it was a new feature of SpringBoot.

2、 Spring

(1) AOP terminology

  1. Inform Advice-what to do in the aspect and when to execute it. When, including before the method call, after the method call, after the method is successfully called, after the method call throws an exception, surround (Around). Surround allows to provide some functions that need to span the method call before and after, such as calculating the call time.
  2. Joinpoint-the point where the aspect can be inserted during application execution. It is actually a logical concept and is not reflected in the configuration.
  3. Pointcut-the specific connection point of the execution notification.
  4. Aspect-notice + point of contact
  5. Introduction-allows adding new methods or properties to the class. (Personal understanding is that the methods and attributes in the application use aspect are as if these methods and attributes are native. You can refer to the aop:declare-parents element)
  6. Weaving-the process of applying aspects to the target object to create a new proxy object. Spring uses the runtime. Compile time and class load time are other ways.

(2) Bean's life cycle
Although it is called the life cycle, it actually refers to which methods the bean calls during initialization and recycling. If you only look at "Spring Actual Combat", you can see a picture similar to the following
Insert picture description here

(3) Cglib and JdkProxy

1. Relationship with Spring

These are two implementations of Spring AOP. According to the official documentation:

  • JdkProxy is used by default
  • For the proxy object does not implement any interface, use Cglib
  • You can force the use of Cglib to be specified. This can explain why some beans implement interfaces and some do not, but they can coexist in the same project.

2. Sample code

//用户管理接口
public interface UserManager {
    
    
    //新增用户抽象方法
    void addUser(String userName,String password);
    //删除用户抽象方法
    void delUser(String userName);
}
//用户管理实现类,实现用户管理接口
public class UserManagerImpl implements UserManager{
    
    
    @Override
    public void addUser(String userName) {
    
    
        System.out.println("调用了新增的方法!");
        System.out.println("传入参数为 userName: "+userName+" password: "+password);
    }
    @Override
    public void delUser(String userName) {
    
    
        System.out.println("调用了删除的方法!");
        System.out.println("传入参数为 userName: "+userName);
    }   
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import com.lf.shejimoshi.proxy.entity.UserManager;
import com.lf.shejimoshi.proxy.entity.UserManagerImpl;
//JDK动态代理实现InvocationHandler接口
public class JdkProxy implements InvocationHandler {
    
    
    private Object target ;//需要代理的目标对象
    
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    
    
        System.out.println("JDK动态代理,监听开始!");
        Object result = method.invoke(target, args);
        System.out.println("JDK动态代理,监听结束!");
        return result;
    }
    //定义获取代理对象方法
    // 因为只是在main()里测试,声明为private了 
    private Object getJDKProxy(Object targetObject){
    
    
        this.target = targetObject;
        return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), targetObject.getClass().getInterfaces(), this);
    }
    
    public static void main(String[] args) {
    
    
        JdkProxy jdkProxy = new JdkProxy();
        UserManager user = (UserManager) jdkProxy.getJDKProxy(new UserManagerImpl());//获取代理对象
        user.addUser("admin");
    }   
}
import java.lang.reflect.Method;

import com.lf.shejimoshi.proxy.entity.UserManager;
import com.lf.shejimoshi.proxy.entity.UserManagerImpl;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

//Cglib动态代理,实现MethodInterceptor接口
public class CglibProxy implements MethodInterceptor {
    
    
    private Object target;//需要代理的目标对象
    
    //重写拦截方法
    @Override
    public Object intercept(Object obj, Method method, Object[] arr, MethodProxy proxy) throws Throwable {
    
    
        System.out.println("Cglib动态代理,监听开始!");
        Object invoke = method.invoke(target, arr);//方法执行,参数:target 目标对象 arr参数数组
        System.out.println("Cglib动态代理,监听结束!");
        return invoke;
    }
    //定义获取代理对象方法
    public Object getCglibProxy(Object objectTarget){
    
    
        //为目标对象target赋值
        this.target = objectTarget;
        Enhancer enhancer = new Enhancer();
        //设置父类,因为Cglib是针对指定的类生成一个子类,所以需要指定父类
        enhancer.setSuperclass(objectTarget.getClass());
        enhancer.setCallback(this);// 设置回调 
        Object result = enhancer.create();//创建并返回代理对象
        return result;
    }
    
    public static void main(String[] args) {
    
    
        CglibProxy cglib = new CglibProxy();
        UserManager user =  (UserManager) cglib.getCglibProxy(new UserManagerImpl());
        user.delUser("admin");
    }
    
}

3. Comparison
Compare the difference between the two. This is also a common interview question.

JdkProxy Cglib
rely The proxy object implements the interface (the sum of the number of methods of all interfaces must be >0[4]) Introduce asm, cglib jar; cannot be final classes and methods
principle Reflection, an anonymous inner class that implements the interface of the proxy object, surrounds the method of the proxy object through InvocationHandler.invoke() Introduce asm, cglib jar, proxy class to implement MethodInterceptor, rewrite bytecode at the bottom to achieve
effectiveness Create fast, run slow (see description 2 below) Slow to create, fast to run

Explanation: How Cglib modifies the bytecode is invisible from the code. Using ASM technology, modify the class file, you can check it yourself. JDK1.8 and later, JdkProxy runs faster than Cglib (before it was slower than Cglib).

4. About org.apoalliance.intercept.MethodInterceptor

class CommonInterceptor implements MethodInterceptor {
    
    
      @Override
      public Object invoke(MethodInvocation invocation) throws Throwable {
    
    
            try {
    
    
                   // 拦截器内部逻辑
                  result = invoication.proceed();
            catch(Throwable e) {
    
    
                  // 异常处理
            }
            return result;
      }
}

Statement proxy chain

@Configuration
public class InterceptorConfig {
    
    

      @Bean
      public CommonInterceptor serviceInterceptor() {
    
    
            CommonInterceptor bean = new CommonInterceptor();
            return bean;
      }

      // 代理名称后缀为servie的实现类
      @Bean
      public BeanNameAutoProxyCreator servieBeanNameAutoProxyCreator() {
    
    
            BeanNameAutoProxyCreator creator = new BeanNameAutoProxyCreator();
            creator.setName("*ServieImpl");
            creator.setInterceptorNames("serviceInterceptor");
            creator.setProxyTargetClass(true);
            return creator;
      }
}

After checking some information, the apoalliance package is only the interface specification of aop, not the specific implementation. Don't confuse the MethodInterceptor here with the MethodInterceptor of cglib.

(4) The difference between construction method injection and set value injection

Note: Set value injection refers to injection via setter.

Put another way:

  1. If you only set the value of basic types (int, long, etc.), it is recommended to set the default value instead of any kind of injection.
  2. Construct injection does not support most dependency injections. The construction injection is only performed at the time of creation, and the value of the setting injection can also be changed later.
  3. Set-value injection can support dependent objects that are not yet complete, but construction injection cannot. The dependency can be determined by constructing injection, so if the dependency does not change, you can also choose dependency injection.

(5) ApplicationContext event

The ApplicationContext event processing can be performed by implementing the ApplicationEvent class and ApplicationListener interface. This is a standard sender-listener model, which can be used to process business logic and decouple code.
However, sending and receiving are actually synchronous. If there is a transaction, they will be in the same transaction and cannot be used as an asynchronous processing mechanism.

3. SpringBoot

(1) Key notes of SpringBoot

The so-called core annotations here refer to some new annotations relative to Spring itself, let's see what they do.
It happens that the annotations mentioned here can be marked in the startup class of SpringBoot (not limited to the startup class), and the following code snippets are used to illustrate.
Code example:

package com.example.demo;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.PropertySource;

@PropertySource(value = "classpath:application.properties")
@MapperScan("com.example.demo.dal")
@SpringBootApplication(scanBasePackages = {
    
    "com.example.demo"})
@Import({
    
    DemoConfig1.class, DemoConfig2.class,})
public class DemoApplication {
    
    
   public static void main(String[] args) {
    
    
   	SpringApplication.run(DemoApplication.class, args);
   }
}

(2) @PropertySource

Read variables from the specified file. The sample code will read the value of the application.properties variable from the resource directory. The format of the file is as follows. You can use constants or variable substitutions to distinguish the values ​​of different environments.

name=value
env.name=$env.value

How to use this value? Just get it where you want to use it.

@PropertySource(value = "classpath:application.properties")
class TestClass {
    
    
	@Resource
	private Environment environment;

      @Test
      public void test() {
    
    
            String value = environment.getProperty("name"));
      }
}

(3) Used in conjunction with @Value

Use @Value to inject the value of the configuration file directly into the member variable.

@PropertySource("classpath:application.properties")
public class PropertyConfig {
    
    
    @Value("${name}")
    private String value;
     ...
}

(4) Quoted by @Import

In the sample code of (1), if there is no @PropertySource on the class, but there is @PropertySource in DemoConfig1 or DemoConfig2, the variables loaded by them can also be read out through @Import.

(5) Properties and .yml configuration files

@PropertySource can only import the content in the .properties configuration file, which is not supported for .yml. After reading some articles, I came to the conclusion that yml files can be imported without annotations, but they need paths.
Springboot has two core configuration files, application and bootstrap, both of which can be in properties or yml format. The difference is that bootstrap is loaded prior to application and cannot be overridden.

(6) @MapperScan

This is actually a mybatis annotation, which is used to generate an implementation class for the DAO interface under the specified path through the sqlmapping.xml file.

(7)@SpringBootApplication

@SpringBootApplication is composed of multiple annotations. The source code is as follows:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
    
     @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
		@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
    
    
      // 略
}

Briefly introduce these annotations:

1. Meta annotation

The top four lines are all meta comments. Recall their role:

  • Where can the @Target annotation be used. TYPE represents the type, such as class, interface, enum
  • @Retention Annotated retention time period. Only the RUNTIME type can get its value through reflection at runtime
  • @Documented Whether this annotation is retained when generating javadoc documents
  • @Inherited Whether the annotated element has inheritance, for example, the subclass can inherit the annotation of the parent class without writing it down explicitly.

2.@SpringBootConfiguration

Annotate that this is a SpringBoot configuration class, which has the same function as @Configuration. It can also be seen from the source code that it directly uses @Configuration.
Recall that the function of the @Configuration annotation is to integrate related @Bean to implement the declaration of the instance, instead of the xml form.

3.@EnableAutoConfiguration

This annotation is the core annotation for automatic configuration and is defined as follows:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
    
    
      // 略
}

With the AutoConfigurationImportSelector introduced by @Import, the SpringBoot application loads all eligible @Configuration configurations into the IoC container created and used by the current SpringBoot. The specific details will not be expanded here. To briefly mention, what is loaded is the configuration of META-INF/spring.factories in the specified configuration file.

4.@ComponentScan

Scan @Service, @Repository, @Component, @Controller, etc. annotated classes to create beans.
You can set the scan range to determine which classes generate beans and which classes do not.

5.@Import

Import external resources (beans, @Configuration configuration classes) into the current IOC container.
Use @Import to instantiate the beans defined in the referenced jar.

4、Starter

Refers to the various starter packages referenced in dependencies. Starter can be regarded as the result of "depending on jar + configuration" packaging. The purpose is to reduce the cost for developers to introduce components without having to sort out dependencies and write configuration files.
The starter follows the principle of "convention is greater than configuration". Most of the configuration of the components used have default values, which can be used directly without declaration.

Simple steps to create a Spring boot:

  1. Create maven project
  2. Create the properties class to save configuration information
  3. Write business function classes (including classes that will be instantiated into beans)
  4. Write Configuration class, define bean
  5. Create a new directory META-INF under the resources folder, create a new spring.factories file in the directory, and
    configure AutoConfiguration in spring.factories
  6. Bale

5. War package

(1) The difference with jar package

  • jar encapsulates classes and related resources
  • war represents a deployable web application

(2) The
general steps for deploying the war package of SpringBoot project are as follows, 1 may need to remove the embedded tomcat, 2 has other forms, because I use thread scripts to package when I work, and I have not actually operated them. The following steps are for reference only .

  • pom.xml is modified to package by war
  • Modify the main entry method, inherit a SpringBootServletInitializer class, and override the configure method
  • maven packaging
  • Copy it to the tomcat path (tomcat needs to be pre-configured) and start it with startup

6, Springboot interview questions supplement

(1) Two ways to use Springboot

  1. Inherit the spring-boot-starter-parent project
<parent>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-parent</artifactId>
     <version>1.5.6.RELEASE</version>
</parent>
  1. Import spring-boot-dependencies project dependencies
<dependencyManagement>
      <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>1.5.6.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
      </dependencies>
</dependencyManagement>
  1. Does SpringBoot need a separate container to run?

No need, built-in containers such as Tomcat/Jetty.
How to use Jetty? Remove the Tomcat dependency and introduce Jetty, and change some application configuration.

  1. What are the ways to run SpringBoot?

Packaged with commands or put in a container to run Run
with Maven/Gradle plug-in
directly execute main method to run

  1. The way to run specific code when SpringBoot starts

Bean can implement the interface ApplicationRunner or CommandLineRunner.

  1. How many ways does SpringBoot implement hot deployment?
    There are two main types:
    Spring Loaded-reference dependency (maven plugin). For annotations and xml changes cannot be sensed and need to be restarted;
    Spring-boot-devtools-reference dependencies, change configuration (optional), start automatic compilation of idea. Note that the production environment plug-in may cause gc.

  2. Is Spring Boot compatible with old Spring projects and how to do it?
    Compatible, use @ImportResource annotation to import old Spring project configuration files.

7, SpringBoot startup principle

The start entry of SpringBoot is at SpringApplication.run(XXXApplication.class, args) in the main method.
Startup diagram: A
Insert picture description here
brief summary:

  • Register various environment variable configurations
  • Register various factories
  • Register various listeners
  • Create context and initialize various beans

In fact, all knowledge is learned. Just learn more. You can learn more at work, but first you must have a good job and a good job opportunity, and a good job is inseparable from technology The level of technology and the level of technology must be improved by learning, so these are all complementary, and you will not get a high return without investing yourself.

I have compiled a lot of Java interview questions, as well as Java learning materials and ways. If you need it, you can click to enter, the code: cszq , which can be provided for free!
Insert picture description here
Insert picture description here

Guess you like

Origin blog.csdn.net/m0_45270667/article/details/108795627