Spring core function - IOC and AOP

overview

Spring is a lightweight, non-intrusive IOC and AOP one-stop Java development framework that emerged in 2003. It was born to simplify enterprise-level development.

Lightweight: The jar package of Spring is about 1M, the resource occupation of the framework is small when running, and the operating efficiency is high

Non-intrusive: Business code does not need to inherit or implement interfaces or classes in Spring to implement business code, but can simplify the development process through configuration files

IOC: Inversion of Control, Spring can help us manage objects in java

AOP: object-oriented programming, reducing code redundancy in the business development process and improving development efficiency

One-stop framework: Spring itself also provides Web functions and data access functions, and can also manage other frameworks

Spring architecture diagram

IOC

        Inversion of control, Inverse of Control referred to as IOC, IOC is a design idea, which is to transfer the power of creating objects in the program to the framework.

        The IOC container is a container with a dependency injection function. The container can help us manage from creating objects, initializing objects, object assembly and external access methods to object destruction. The IOC container is similar to a Map collection. After the object is created, it will be added to this collection. The key value stores the name or class name of the object, and the value stores the address of the object. When you need to use the object, you don't need to create the object manually, you can get it directly from the container.

The concept of beans

Objects managed by Spring are collectively referred to as bean objects

Manage bean objects through XML configuration

Configure the object through the bean tag in the Spring configuration file

    <bean id="admin" class="com.yzl.spring.model.Admin" scope=""></bean>

Attributes in the bean tag :

id : object name

name : the alias of the object, which can be composed of multiple

class : the full class name, creating objects through the reflection mechanism

scope : the mode of the object, consisting of two values: singleton and prototype

        singleton (default value): There is only one bean instance in Spring, singleton mode.

        prototype: the object is created every time the object is used

request : Each http request will create a bean, only used in the WebApplicationContext environment

session : The same http session shares a bean, different sessions use different beans, and the usage environment is the same as above

The way of dependency injection (DI) in xml :

During the process of creating an object in Spring, object dependency properties (simple values, collections, objects) are set to the object through configuration.

For example, when configuring the adminService object, inject the adminDao object dependency into the object

    <bean id="adminService" class="com.yzl.spring.service.AdminService">
        <property name="adminDao" ref="adminDao"></property><!--依赖注入-->
    </bean>

Manage bean objects through annotations

Preparation

First, you need to import the jar required by the annotation, which is usually automatically imported when importing the jar dependency of spring

Then you need to configure the annotations in the spring configuration file

<context:component-scan base-package="com.yzl.spring"></context:component-scan>

There is also a prerequisite for this configuration that the constraints of the configuration need to be added

xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation=
       "http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd"

Some common constraints in spring configuration

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd">
    
</beans>

Relevant notes on managing beans

@Component(value="user"), this annotation is generally used for entity classes to inject objects of this class into the container, which is equivalent to the xml configuration

< bean id="user" class="">< /bean>

@Service(value="user"), used to inject the class object of the Servic layer into the container

@Repository(value="user"), used to inject the class object of the Dao layer into the container

@Scope(value="prototype"), used to indicate the mode of the class object, which is equivalent to the scope attribute of the bean tag

The first three annotations have the same function, but are applied to objects of different layers

Automatic injection of annotation tags

@Autowired

        This tag is an annotation provided by the Spring framework that can be written on fields and setter methods. If it is written on the field, then there is no need to write the setter method. By default, it requires that the dependent object must exist (that is, it has been injected into the container). If null values ​​are allowed, you can set its required attribute to false.

This annotation has two ways of matching objects:

1.byType

This annotation uses this method for automatic injection by default. When injecting, the object is queried by the type of the object

2.byName

This method is to search through the id attribute value defined by the object. It needs to be used with the @Qualifier(value = "") tag, and the value value is the id attribute of the object

@Resource

This tag is provided by jdk, similar to the usage of @Autowired

This annotation also has two ways of matching objects:

1.byType

Use this method by default

2.byName

@Resource(name="")

Advantages and disadvantages of XML configuration and annotations

annotation:

        Advantages: convenient, intuitive, high efficiency, no configuration required

        Disadvantages: Modifications require recompilation of the code before deployment

XML configuration:

        Advantages: XML configuration modification does not require recompilation

        Disadvantages: the development workload is large, and the development requirements of configuration are many

AOP

        Aspect Oriented Programming (Aspect Oriented Programming) is referred to as AOP. The core idea of ​​AOP is to isolate business logic code from non-business logic code and reduce the coupling between business code and non-business code. AOP can extract non-business code and add non-business code functions without modifying the original business code. This can improve code reuse rate and development efficiency

Note: Non-business codes include, for example, printing logs, transaction submission, exception handling, etc.

Role: reduce duplication of code, focus on business development, improve efficiency

The difference between AOP and OOP:

OOP is an abstract encapsulation of the attributes and behaviors of entities in the business to obtain a clearer logical unit

AOP is to isolate business code and non-business code in the process of business processing. For example, business code and non-business code can be regarded as codes of different aspects, and the codes of each aspect are isolated to reduce the coupling of code.

The underlying implementation of AOP in Spring is realized through dynamic proxy, which can be simply understood as, when business code needs to call non-business code, the proxy object generated by the framework is provided to call non-business code

Basic Concepts in AOP

Connection point: A method that can be enhanced in a class is called a connection point, and enhancement means that new functionality can be added

Entry point: The method that is actually enhanced in the class is called the entry point

Notification: The enhanced specific function in the entry point is called notification, which can be divided into pre-notification, post-notification, exception notification, final notification and surrounding notification by calling the time point according to the notification

Aspect: Advise the entire process that is invoked by the pointcut

Target: the target object of the agent (connection point, class where the entry point is located)

Proxy: Proxy object created when notification is applied to target object

AspectJ

AOP is not a unique programming idea in Spring. In fact, many frameworks have implemented the AOP programming idea. AspectJ is an AOP programming framework based on the java language. The implementation method is convenient and supports annotation-based development. Spring introduces the framework realization of

Realize the construction of AOP function in Spring:

First, increase the jar dependency of AspectJ

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>5.2.2.RELEASE</version>
</dependency>

1. Implementation based on xml configuration

<!--首先将通知所在的类对象注入Ioc容器中-->
<bean id="aopdemo" class="com.ff.spring.aop.AopDemo"></bean>
<aop:config>
    <!-- 配置切入点 -->
    <aop:pointcut expression="execution(*
    com.ff.spring.service.UserService.adduser(..))" id="adduser"/>
    <aop:pointcut expression="execution(*
    com.ff.spring.service.UserService.*(..))" id="allmethod"/>
    <!-- 配置通知和切入点 -->
    <aop:aspect ref="aopdemo">
        <aop:before method="savelog" pointcut-ref="adduser"/>
        <aop:after method="savelog" pointcut-ref="adduser"/>
        <aop:round method="aroundAdvice" pointcut-ref="adduser"/>
        <aop:after-throwing method="exceptionAdvice" pointcut-ref="allmethod" throwing="e" />
    </aop:aspect>
</aop:config>

The value of the expression attribute in the <aop:pointcut> tag is the expression of the business code method

Fixed format: execution (return value full class name. method name (..))

return value * substitutes for any type of return value

The class name uses * to represent all classes such as com.example.test.*

The method name can use * to represent all methods

The parentheses after the method represent the parameter list ".." represents the parameter length of any length. If it is not filled, it represents the method without parameters

notification type

Pre-notification: call notification before business code

<aop:before method="savelog" pointcut-ref="adduser"/>

Where method means notification, and pointcut-ref means entry point

Post-notification: call after the business code, if there is an exception in the business code, it will not be called again

<aop:after-returning method="savelog" pointcut-ref="adduser"/>

Exception notification: This notification will be called when an exception occurs in the business code

<aop:after-throwing method="exceptionAdvice" pointcut-ref="allmethod" throwing="e" />

Throwing indicates the parameters passed in the notification, and a parameter of the Throwable class needs to be defined in the parameter list of the exception notification

Final notice: will be called regardless of whether there is an exception in the business code

<aop:after method="savelog" pointcut-ref="adduser"/>

Surround notification: The above four notification calls can be implemented separately and simultaneously

<aop:round method="aroundAdvice" pointcut-ref="adduser"/>

In the surround notification, a parameter of the ProceedingJoinPoint class needs to be passed in, which represents the entry point

The implementation of surround notification:

The proceed() method in the ProceedingJoinPoint class represents the execution entry point. The code corresponding to the relative position called by this method corresponds to different types of notifications. For example, the code written earlier represents the pre-notification, and the code in the catch code block is the exception notification.

public void aroundAdvice(ProceedingJoinPoint point){
        try {
            System.out.println("前置通知");
            point.proceed();
            System.out.println("后置通知");
        } catch (Throwable throwable) {
            throwable.printStackTrace();
            System.out.println("异常通知"+throwable.getMessage());
        }
        System.out.println("最终通知");
 }

2. Implementation based on annotations

① First, you need to add aop annotation support <aop:aspectj-autoproxy /> in the configuration file

② Use @Component and @Aspect annotations on the fields of the AOP code class. The former is to inject the object of this class into the Ioc container, and the latter is to represent that the class is an aspect class

@Component
@Aspect//Indicates that the class is an aspect class
public class MyUtil {}

③Use the corresponding notification annotation on the notification field

Pre-notification: @Before("execution(* com.yzl.spring.dao.AdminDao.save(..))")

Post notification @AfterReturning("execution(* com.yzl.spring.dao.AdminDao.save(..))")

Exception notification: @AfterThrowing(value = "execution(* com.yzl.spring.dao.AdminDao.save(..))", throwing = "e")

Final notification: @After("execution(* com.yzl.spring.dao.AdminDao.save(..))")

Around advice: @Around("execution(* com.yzl.spring.dao.AdminDao.save(..))")

The parameters of the notification content write the expression of the corresponding method of the business code, where notifications that require multiple parameters, such as exception notifications, need to use the value attribute value to write an expression to distinguish the parameters in the throwing attribute value

    //前置通知
    @Before("execution(* com.yzl.spring.dao.AdminDao.save(..))")
    public void printLog(){
        System.out.println("打印日志");
    }
    //后置通知
    @AfterReturning("execution(* com.yzl.spring.dao.AdminDao.save(..))")
    public void commit(){
        System.out.println("事物提交");
    }
    //异常通知
    @AfterThrowing(value = "execution(* com.yzl.spring.dao.AdminDao.save(..))",throwing = "e")
    public void exceptionService(Throwable e){
        System.out.println("异常通知"+e.getMessage());
    }
    //最终通知
    @After("execution(* com.yzl.spring.dao.AdminDao.save(..))")
    public void finalAdvic(){
        System.out.println("最终通知");
    }
    //环绕通知
    @Around("execution(* com.yzl.spring.dao.AdminDao.save(..))")
    public void aroundAdvice(ProceedingJoinPoint point){
        try {
            System.out.println("前置通知");
            point.proceed();
            System.out.println("后置通知");
        } catch (Throwable throwable) {
            throwable.printStackTrace();
            System.out.println("异常通知"+throwable.getMessage());
        }
        System.out.println("最终通知");
    }

Guess you like

Origin blog.csdn.net/yzl1293346757/article/details/128223268