Spring

Full stack open source framework

I. Problems solved

1. The IOC decouple

Through Spring’s IOC container, dependencies between objects are handed over to Spring to avoid hard-coded program coupling.

2. Simplify AOP programming

Spring’s AOP capabilities make it easier to do section-oriented programming.

3. Declarative Transaction @transaction

Transaction control can be done through annotations.

4. Integrate various frameworks and APIS to reduce the difficulty of use

Frameworks: Struts, Hibernate, MyBatis, Hessian, Quartz

API : JDBCTemplate、 JavaMail、RestTemplate

Second, core ideas

IOC Inversion of Control

Delegating the creation and management of Java objects to third parties (Spring Framework)

Purpose: To uncouple

How it works: Call the no-argument constructor through reflection to instantiate an object and store it in a container. No no-argument construct will fail to instantiate

2. DI Dependancy Injection 3

Assigns a managed Java object to a property

Purpose: To uncouple

Principle: Use reflection technology to set target object properties

AOP Aspect oriented Programming

A horizontal extraction technique that runs specific logic before and after specific methods

Purpose: To reduce duplicate code

Application scenarios: transaction control, permission verification, log recording, and performance monitoring

Special classes

  1. BeanFactory – Top level interface for container classes – base specification

    1. ApplictaionContext – Advanced interface for container classes – Internationalization, Resource Access (XML, configuration classes)

      1. ClassPathXmlApplicationContext – project root directory path loading configuration document

      2. FileSystemXmlApplicationContext – hard drive path under loading configuration document

      3. AnnotationConfigApplicationContext – from annotation configuration class loading configuration

  2. FactoryBean – Custom complex Bean creation process

  3. BeanFactoryPostProcessor – After BeanFactory is initialized, it is postprocessed

  4. Beanpostprocessor-bean objects are instantiated, dependency injected, and post-processed at the Bean level

Four, annotations,

1. The IOC type

  1. @Component(“Bean ID”) [class] – The default ID is lowercase, equivalent to three annotations

    1. @Controller

    2. @Service

    3. @Repository

  2. @scope (“Bean lifecycle “)

    1. Singleton [default] – Same as container life cycle

    2. Prototype – Each fetch is new

    3. Request – An HTTP request within the same range

    4. Session-same in session scope

    5. The application scope of globalsession-portlet-based is the same

  3. @postconstruct – call after initialization

  4. @predeStory – Called before destruction

2. DI type

  1. @autoweird – Inject by type

    You can use it with @Qualifier(name=”Bean ID”) if the object corresponding to the type is not unique

  2. @resource (name=”Bean ID”, type= class) – Inject by ID by default, or by type if ID cannot be found

3. Configure the type

  1. @ComponentScan – The package path to be scanned
  2. @configuration – Indicates that this class is a Configuration class
  3. @propertysource – Introduces external configuration documentation
  4. @import – Loads other configuration classes
  5. @value – Assigns a Value to the property from the configuration document
  6. @bean – Stores the object returned by the method into the IOC container. The object ID is the method name, which can also be specified manually

4. Type of AOP

  1. @pointcut – Configures pointcuts
  2. @before-Pre-notification
  3. @afterRETURNING – Post notification
  4. AfterThrowing – Exception notification
  5. @after – Final notice
  6. @around – Circular notification

Five, the AOP

1. The term

  1. Joinpoint Joinpoint: all methods
  2. PointCut: The specific method you want to influence
  3. Advice/enhancement: crosscutting logic
  4. Target Target: The object to be proxied
  5. Proxy: An enhanced class woven into AOP
  6. Weaving in: Applying Advice to Target to generate a Proxy
  7. Aspect Aspect: Pointcut + enhancement

Purpose: To lock what crosscutting logic is inserted where

@Component
@Aspect
public class LogUtil {
    
     /** * Pointcut expression * [access modifier] return value package name. Package name Package name Class name Method name (parameter table) * * [.] used to denote any package. Used in packages to indicate the current package and its subpackages * * [..] * 【*】 Used in the parameter table, means at least one parameter */
     @Pointcut("execution(* com.lagou.service.impl.*.*(..) )"
     public void pointcut(a){}
    
     @Before("pointcut()")
     public void beforePrintLog(JoinPoint jp){
         Object[] args = jp.getArgs();
         System.out.println("Pre-notification: beforePrintLog, parameter is:" + Arrays.toString(args));
     }
    
     @AfterReturning(value = "pointcut()",returning = "rtValue")
     public void afterReturningPrintLog(Object rtValue){
         System.out.println("AfterReturningPrintLog, return value:+ rtValue);
     }
    
     @AfterThrowing(value = "pointcut()",throwing = "e")
     public void afterThrowingPrintLog(Throwable e){
     	System.out.println("Exception notification: afterThrowingPrintLog, exception is:"+ e);
     }
    
     @After("pointcut()")
     public void afterPrintLog(a){
     	System.out.println("Final notification: afterPrintLog");
     }
    
     /** * wrap around notification */
     @Around("pointcut()")
     public Object aroundPrintLog(ProceedingJoinPoint pjp){
         
         // Define the return value
         Object rtValue = null;
         try{
             
             // Pre-notification
             System.out.println("Advance notice");
             
             // 1. Obtain parameters
             Object[] args = pjp.getArgs();

             // 2. Run pointcut methods
             rtValue = pjp.proceed(args);

             // post notification
             System.out.println("Post notification");
             
         } catch (Throwable t){
             
             // Exception notification
             System.out.println("Exception notification");
             t.printStackTrace();
             
         }finally {
             
             // Final notification
             System.out.println("Final notice");
             
         }
         returnrtValue; }}Copy the code

Declarative Transaction @transaction

1. Four features

Atomicity: Operations either all occur or none

Consistency: Transitions from one consistent state to another

Isolation: Transactions cannot be disturbed by other transactions

Durability: Data changes are permanent

2. Isolation level

Dirty Read: Reads data that is not Committed in another transaction. – Read Committed Reads

Repeatable Read: reads data from another update transaction and has different data contents. – Repeatable Read Indicates Repeatable Read

Phantom read: data read to another transaction INSERT or DELETE with different amounts of data read – Serializable

3. Communication behavior

  1. REQUIRED [default] – If there are no transactions, create a new one, and if one already exists, join it
  2. SUPPORTS – SUPPORTS the current transaction. If there is no transaction currently, it runs in a non-transactional manner – lookup
  3. Mandatory-use the current transaction, and throw an exception if there is no transaction currently
  4. REQUIRES_NEW – Creates a new transaction and suspends the current transaction if one exists
  5. NOT_SUPPORTED – Runs the operation in a non-transactional manner and suspends the current transaction if one exists
  6. NEVER – Runs non-transactionally and throws an exception if a transaction currently exists
@Transactional(readOnly = true, propagation = Propagation.SUPPORTS)
Copy the code

4. Failure scenario

  1. Apply to methods that are not public
  2. Method calls in the same class
  3. Exception is eaten by a try catch
  4. Propagation setting error
  5. The rollbackFor setting is incorrect
  6. The database engine does not support transactions

Principle 5.

○ Through JDK dynamic proxy and Cglib dynamic proxy implementation, database transactions are ultimately a Connection transaction

○ Connection is obtained from the Connection pool (C3P0, Druid). Preparedstatements can be generated. Preparedstatements can run SQL statements directly by running the execute() method

○ In JDK 1.8, JDK dynamic proxies have better performance than Cglib dynamic proxies, but the disadvantage is that the proxied classes using JDK dynamic proxies need to implement at least one interface

1. JDK dynamic proxy

The proxied class must implement at least one interface

public class JdkDynamicProxyTest implements InvocationHandler {

    private Target target;

    private JdkDynamicProxyTest(Target target) {
        this.target = target;
    }

    public static Target newProxyInstance(Target target) {
        return (Target) Proxy.newProxyInstance(JdkDynamicProxyTest.class.getClassLoader(),
                newClass<? >[]{Target.class},new JdkDynamicProxyTest(target));

    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        returnmethod.invoke(target, args); }}Copy the code

2. Cglib dynamic proxy

This is done by bytecode subclass inheritance

public class CglibProxyTest implements MethodInterceptor {

    private CglibProxyTest(a) {}public static <T extends Target> Target newProxyInstance(Class<T> targetInstanceClazz) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(targetInstanceClazz);
        enhancer.setCallback(new CglibProxyTest());
        return (Target) enhancer.create();
    }

    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        returnproxy.invokeSuper(obj, args); }}Copy the code

test

Target targetImpl = new TargetImpl();
Target dynamicProxy = JdkDynamicProxyTest.newProxyInstance(targetImpl);
Target cglibProxy = CglibProxyTest.newProxyInstance(TargetImpl.class);
Copy the code

Spring Bean lifecycle

  1. The reflection call constructs the instantiation Bean without arguments
  2. Set property values using reflection
  3. If the Bean implements the BeanNameAware interface, the setBeanName() method is called to pass in the ID value of the current Bean
  4. If the Bean implements the BeanFactoryAware interface, the setBeanFactory() method is called to pass in a reference to the current factory instance
  5. If the Bean implements the ApplicationContextAware interface, the setApplictaionContext() method is called to pass in a reference to the current ApplicationContext instance
  6. If the Bean associated with BeanPostProcessor call postProcessBeforeInitialization () method, the Bean processing – Spring AOP in this implementation
  7. If the Bean implements the InitializingBean interface, the afterPropertiesSet() method is called
  8. If the init-method property is specified in the configuration document, the method specified by that property is called
  9. If the Bean associated with BeanPostProcessor call postProcessAfterInitialization () method, the Bean can be used in the application
  10. If the scope of the Bean is singleton, place the Bean in an IOC container; If the scope is Prototype, hand the Bean to the caller
  11. If the Bean implements the DisposableBean interface, the destory() method will be called when the Bean is destroyed – if the destory-method property is set in the configuration document, the method specified by this property will be called

Spring Bean loop dependencies

process

  1. SpringBean A is instantiated, putting itself into the three-level cache, and during the instantiation process, SpringBean B is found to be dependent
  2. SpringBean B is instantiated, putting itself into the three-level cache, and during the instantiation process, SpringBean A is found to be dependent
  3. SpringBean B goes to the level 3 cache to get SpringBean A, which is not yet formed
  4. Upgrade SpringBean A to level 2 cache and do some scaling
  5. SpringBean B puts itself into level 1 cache once it is created
  6. SpringBean A gets SpringBean B from the level 1 cache

Unable to process scenarios

  • Singleton Bean constructor loop dependencies
  • Multi-instance Bean loop dependencies