Getting started with Spring Basics

1. Introduction

Spring is an open source framework created by Rod Johnson. It is created to solve the complexity of enterprise application development.

In the presentation layer, it provides the integration function of Spring MVC and Struts framework;
In the business layer, you can manage transactions, record logs, etc;
In the persistence layer, technologies such as Mybatis, Hibernate and JdbcTemplate can be integrated;
Therefore, it can be said that Spring is a good "one-stop" choice for enterprise application development. Although Spring runs through the presentation layer, business logic layer and persistence layer, it does not want to replace those existing frameworks, but seamlessly integrate them with a high degree of openness.

  • Objective: to solve the complexity of enterprise application development
  • Function: use basic JavaBean s instead of EJB s, and provide more enterprise application functions
  • Scope: any Java application

Maven package to import:

<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.3.8</version>
</dependency>

2. Composition

The Spring framework is a layered architecture consisting of seven modules

  1. Spring core: the core container provides the basic functions of the spring framework. The main component of the core container is BeanFactory, which is the implementation of the factory pattern. BeanFactory uses the inversion of control (IOC) pattern to separate the configuration and dependency specifications of the application from the actual application code.

  2. Spring context: a spring context is a configuration file that provides context information to the spring framework. The spring context includes enterprise services, such as JNDI(Java Naming and Directory Interface), EJB(Enterprise Java Beans are called Java enterprise beans), e-mail, internationalization, checksum and scheduling functions.

  3. Spring AOP: through the configuration management feature, the spring AOP module directly integrates aspect oriented programming functions into the spring framework. Therefore, you can easily make any object managed by the spring framework support AOP. The spring AOP module provides transaction management services for objects in spring based applications. By using spring AOP, declarative transaction management can be integrated into applications without relying on EJB components.

  4. Spring DAO: the JDBC DAO abstraction layer provides a meaningful exception hierarchy that can be used to manage exception handling and error messages thrown by different database vendors. The exception hierarchy simplifies error handling and greatly reduces the amount of exception code that needs to be written (such as opening and closing connections). Spring DAO's JDBC oriented exceptions follow a common DAO exception hierarchy.

  5. Spring ORM: the spring framework inserts several ORM frameworks to provide ORM object relationship tools, including JDO, Hibernate and iBatis SQL Map. All of this follows spring's common transaction and DAO exception hierarchy.

  6. Spring Web module: the Web context module is built on the application context module and provides context for web-based applications. The web module also simplifies processing multipart requests and binding request parameters to domain objects.

  7. Spring MVC framework: the MVC framework is a fully functional MVC implementation for building Web applications. Through the policy interface, the MVC framework becomes highly configurable. MVC accommodates a large number of view technologies, including JSP.

3. IOC theory overthrow

1. Review MVC development first

The general mode is:

  • UserDao interface
  • UserDaoImpl implementation class
  • UserService business interface
  • UserServiceImpl business implementation class

According to the traditional programming, this mode is realized one by one. The process is as follows:

  1. The codes of each module are as follows:
  • UserDao interface
public interface UserDao {
    void getUser();
}
  • UserDaoImpl implementation class
public class UserDaoImpl implements UserDao{
    public void getUser() {
        System.out.println("Get user default data");
    }
}
  • UserService business interface
public interface UserService {
    void getUser();
}
  • UserServiceImpl business implementation class
public class UserServiceImpl implements UserService{
    private UserDao userDao= new UserDaoImpl();
    public void getUser() {
        //The business layer is transferred to the DAO layer, and the combination mode is used
        userDao.getUser();
    }
}

Next, you need to create a test class MyTset

public class MyTest {
    public static void main(String[] args) {
        //In the three-tier architecture, users call the business layer, and they do not need to contact the DAO layer
        UserService userService = new UserServiceImpl();
        userService.getUser();
    }
}

2. Introduction of IOC ideas

Assuming that the user requirement changes from "obtaining user data by default" to "obtaining user data using Mysql", you need to add a UserDaoMysqlImpl class under the dao package and change the UserServiceImpl business implementation class to:

public class UserServiceImpl implements UserService{
    private UserDao userDao= new UserMySqlImpl();
    public void getUser() {
        //The business layer is transferred to the DAO layer, and the combination mode is used
        userDao.getUser();
    }
}

This brings a problem: once the user needs change, the original code needs to be changed. If the amount of code is huge, the maintenance and development cost is too large, time-consuming and laborious.

To solve this problem, it can be changed as follows:

  1. Add a set interface in the service layer
public interface UserService {
    void getUser();
    void setUserDao(UserDao userDao);
}
  1. The UserServiceImpl business implementation class changes to:
public class UserServiceImpl implements UserService{
    private UserDao userDao;
    //Dynamic value injection using set
    @Override
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
    @Override
    public void getUser() {
        //The business layer is transferred to the DAO layer, and the combination mode is used
        userDao.getUser();
    }
}
  1. MyTest.java becomes:
public class MyTest {
    public static void main(String[] args) {
        //In the three-tier architecture, users call the business layer, and they do not need to contact the DAO layer
        UserService userService = new UserServiceImpl();
        userService.setUserDao(new UserOracleImpl());
        userService.getUser();
    }
}

In this way, what the user needs does not depend on the programmer. The user can pass the written interface implementation class as a parameter.

4. The first hello spring

Let's talk about the idea I understand: after java creates the object, we hand it over to Spring for management. When we need to use it, we can get it from Spring.

Each entity class needs to set the set method (principle: IOC theory), otherwise the Spring configuration will report an error.

  1. Create an entity class (pojo):
public class Hello {
    private String str;

    public String getStr() {
        return str;
    }
    public void setStr(String str) {
        this.str = str;
    }
    @Override
    public String toString() {
        return "Hello{" +
                "str='" + str + '\'' +
                '}';
    }
}
  1. Create a Bean.xml file (Spring configuration file), which is the configuration template used every time:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">


</beans>

ips: ieda can automatically generate Spring configuration files. Right click and select new - > XML configuration file - > Spring configuration file

  1. On the basis of the above entity class, configure a bean.xml object:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--    use spring To create an object, in spring These are called Bean -->
    <bean id="hello" class="cn.sdablog.pojo.Hello">
        <property name="str" value="Spring"/>
    </bean>

</beans>
parameterdescriberemarks
beanRepresents an object (equivalent to a new object in java), and multiple objects can be setlabel
idClass name of the objectattribute
classclass object requiring newattribute
propertySet a value for the property in the objectSub label
nameProperty name set in entity classChild label properties
valueThe value set for the propertyChild label properties

Tip:
If the entity class is managed by Spring, you can see a small leaf on the entity class. Click to jump to the corresponding configuration xml.

  1. A test class MyTest:
public class MyTest {
    public static void main(String[] args) {
        //Get spring context object
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        //Our objects are now managed in spring. We just need to get them directly
        Hello hello = (Hello) context.getBean("hello");
        System.out.println(hello.toString());
    }
}

Note: "ApplicationContext context = new ClassPathXmlApplicationContext(" beans.xml ")" this is fixed code, which is to obtain the object in your bean file and assign it to the context.

getBean method: get the object in Spring (pass in the object name).

Output results:

Note: the implementation class obtained by the Spring container through id instantiates the parameterless structure by default.

5. IOC creation method

  1. Create objects using parameterless construction (default)
  2. Creating objects with parametric constructs
  • Subscript assignment
<bean id="hello" class="cn.sdablog.pojo.Hello">
     <constructor-arg index="0" name="name" value="Zhang San"/>
</bean>

In the parameterized construction of hello class, the number of parameters.

  • Parameter name
<bean id="hello" class="cn.sdablog.pojo.Hello">
     <constructor-arg name="name" value="Zhang San"/>
</bean>

6. Spring configuration description

6.1 alias

<!-- Alias. If an alias is added, you can use the alias to get this object-->
<alias name="userDao" alias="hello2"/>

6.2 Bean configuration

<!--    id:bean Unique identification of
        class: bean Fully qualified name corresponding to the object, package name+type
        name: It's an alias, and name Multiple aliases can be taken at the same time
-->
    <bean id="hello" class="cn.sdablog.pojo.Hello" name="hello3">
        <property name="name" value="Zhang San"/>
    </bean>

6.3import

This import is generally used for team development. Multiple configuration files can be imported and merged into one

  • applicationContext.xml
<import resource="beans.xml"/>
<import resource="beans1.xml"/>
<import resource="beans2.xml"/>

7. Dependency injection

7.1 constructor injection

  1. Parametric construction of entity class
    public Hello(String name) {
        this.name=name;
    }
  1. bean.xml
<!--    Constructor injection, subscript assignment-->
    <bean id="hello" class="cn.sdablog.pojo.Hello">
        <constructor-arg index="0" name="name" value="Zhang San"/>
    </bean>

7.2 Set injection (key)

  • Dependency injection: set injection
    • Dependency: the creation of bean objects depends on the framework
    • Injection: all attributes in the bean object are injected by the container

Different types of injection methods:

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

    <bean id="address" class="cn.sdablog.pojo.Address"/>
    <bean id="student" class="cn.sdablog.pojo.Student">
        <!-- Universal injection, value-->
        <property name="name" value="Zhang San"/>
        <!-- Bean Injection, ref -->
        <property name="address" ref="address"/>
        <!-- Array injection-->
        <property name="books">
            <array>
                <value>The Dream of Red Mansion</value>
                <value>Journey to the West</value>
                <value>Romance of the Three Kingdoms</value>
            </array>
        </property>
        <!-- List injection-->
        <property name="hobys">
            <list>
                <value>hobby</value>
                <value>listen to the music</value>
                <value>Ann film</value>
            </list>
        </property>
        <!-- Map injection-->
        <property name="card">
            <map>
                <entry key="ID" value="1324654"/>
                <entry key="bank card" value="1s4444"/>
            </map>
        </property>
        <!-- set injection-->
        <property name="game">
            <set>
                <value>LOL</value>
                <value>Stimulate the battlefield</value>
            </set>
        </property>
        <!-- null injection-->
        <property name="wife">
            <null/>
        </property>
        <!-- Properties injection-->
        <property name="info">
            <props>
                <prop key="Student number">20202145</prop>
                <prop key="Gender">male</prop>
            </props>
        </property>
    </bean>

</beans>

7.3 scope of bean

  1. Singleton mode (Srping default mechanism)
<bean id="userDao" class="cn.sdablog.dao.UserDaoImpl" scope="singleton"/>
  1. Prototype mode: each time an object is created from the container, a new object is generated
<bean id="userDao" class="cn.sdablog.dao.UserDaoImpl" scope="prototype"/>
  1. Other scopes: used in web Development

8. Automatic assembly of bean

  • Automatic assembly is a way for Spring to meet the needs of bean s
  • Spring will automatically find in the context and automatically assemble properties for the bean

There are three ways to assemble in Spring

  1. Configuration displayed in xml
  2. Configuration displayed in java
  3. Implicit automatic assembly bean [important]

The autowire attribute of the bean has five attributes:

Attribute valueexplain
Default (default)It is determined by the default autowire attribute value of < beans > parent tag < beans >. For example, < beans default autowire = "ByName", the attribute value corresponding to the autowire attribute in the < bean > element is ByName
ByNameAutomatically assemble according to the name of the attribute. The container will find the Bean exactly consistent with the attribute according to the name, and automatically assemble the attribute
buTypeIt is assembled according to the data type field of the attribute. If the data type of one bean is compatible with the data type of the attribute in another bean, it will be assembled automatically
constructorAutomatically assemble byType mode according to the data type of constructor parameters
noBy default, automatic assembly is not used, and bean dependencies must be defined through the ref element

8.1 ByName auto assembly

Displayed dependency injection relationships (bean.xml configuration file):

<bean id="cat" class="cn.sdablog.pojo.Cat"/>
<bean id="dog" class="cn.sdablog.pojo.Dog"/>
<bean id="person" class="cn.sdablog.pojo.Person">
    <property name="name" value="Zhang San"/>
    <property name="cat" ref="cat"/>
    <property name="dog" ref="dog"/>
</bean>

byname auto assembly:

    <bean id="cat" class="cn.sdablog.pojo.Cat"/>
    <bean id="dog" class="cn.sdablog.pojo.Dog"/>
<!--
    byName: Automatically find your own objects in the container context set Corresponding after method beanid
-->
    <bean id="person" class="cn.sdablog.pojo.Person" autowire="byName">
        <property name="name" value="Zhang San"/>
    </bean>

Setting the byname attribute will match whether the set attribute names in the entity class are equal according to the id name of your bean. If they are equal, they will be assembled automatically. Otherwise, the assembly fails and an error will be reported.

8.2 ByType automatic assembly

ByType auto assembly:

    <bean id="cat1" class="cn.sdablog.pojo.Cat"/>
    <bean id="dog" class="cn.sdablog.pojo.Dog"/>
<!--
    byType: Automatically find your own objects in the container context set Corresponding type in method
-->
    <bean id="person" class="cn.sdablog.pojo.Person" autowire="byType">
        <property name="name" value="Zhang San"/>
    </bean>

Beans are assembled according to type, so the id name of the bean is optional
Insert the code slice here

8.3 automatic assembly using annotations

Official website link: https://docs.spring.io/spring-framework/docs/5.2.7.RELEASE/spring-framework-reference/core.html#beans-annotation-config

  1. Import corresponding constraints
<?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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">

    <context:annotation-config/>

</beans>
  1. Configure annotation support
<context:annotation-config/>

@Autowired(require = false or true)

  1. It can be used directly on the attribute or set mode. The require parameter indicates whether an error will be reported if it does not exist in the container. The default is require=true

  2. Using @ Autowired, we don't need to write a Set method. The premise is that your auto assembled attribute exists in the IOC (Spring) container (there needs to be a get method). By default, it will be automatically assembled according to byType

  3. If you encounter multiple bean s of the same type, you can cooperate with @ Qualifier(value = "xxx") to automatically assemble them according to byName.

    • If there are multiple id entical beans with different IDS, an error will be reported if @ Autowired is used directly, because the bean does not know which bean to assemble
    • Specify the id of the bean with @ Qualifier, and the bean will know which bean to assemble

@Resource(name = "xxx")

The JDK comes with a name = "xxx" that can be configured to specify the bean id for assembly. It is assembled by byName by default. If the corresponding bean cannot be found, it is assembled by byType.

Note: the use of Resource is the jdk's own package, and the following dependent packages need to be imported

<dependency>
            <groupId>javax.annotation</groupId>
            <artifactId>javax.annotation-api</artifactId>
            <version>1.3.2</version>
        </dependency>

Summary:
@Difference between Resource and @ Autowired:

  1. They are used for automatic assembly and can be placed in the attribute field
  2. @Autowired is implemented by byType, and this object must exist. If the type is found to be greater than 1, it will be assembled according to byName [common]
  3. @Resource is implemented by byname by default. If the name cannot be found, it is implemented by byType! If both cannot be found, an error will be reported! [common]
  4. The execution order is different: @ Autowired is implemented by byType and @ Resource is implemented by byName.

9. Develop @ Component using annotations

  1. Before using annotation development, you need to ensure that the AOP package is imported normally
  2. To use annotations, you need to import context constraints and add annotation support.
<?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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">
    <!--Enable annotation support-->
    <context:annotation-config/>

</beans>

9.1 use of component

  1. You can use spring's scanning mechanism to annotate and parse all Bean classes under the specified package (recommended)
<!-- Specify the package to be scanned, and the annotations under the package will take effect.-->
<context:component-scan base-package="cn.sdablog.pojo"/>

All bean classes under the package do not need to be configured one by one. Just add @ Component to the class to be used for declaration.

9.2 attribute injection:

use@Value You can inject attributes and objects, which is equivalent to<property name="name" value="Zhang San"/>
package cn.sdablog.pojo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class User {
    public String name;
    //amount to:
    // <bean id="user" class="cn.sdablog.pojo.User">
    //        < property name = "name" value = "Zhang San" / >
    //  </bean>
    @Value("Zhang San")
    public void setName(String name) {
        this.name = name;
    }
}

9.3 derived notes

@Component has several derived annotations. In web development, MVC three-tier architecture is installed
The functions of these four annotations are the same. They all represent registering a class in Spring and assembling bean s

annotationUse hierarchyeffect
@ControllerController layer (injection service)Used to label control layer components (such as action in struts)
@ServiceService layer (dao injection)Used to label business tier components
@RepositoryPersistence layer (dao access)Used to label data access components, i.e. DAO components
@ComponentAnnotate a Bean whose class is spring container (instantiate ordinary pojo into spring container, which is equivalent to that in configuration file)@Component generally refers to components. When components are difficult to classify, we can use this annotation to mark them as a Bean.

9.4 summary

xml and annotations:

  • xml is more versatile, applicable to any occasion, and easy to maintain
  • Annotations are not their own classes and cannot be used. Maintenance is relatively complex

xml and annotation best practices:

  • xml is used to manage bean s
  • Annotations are only responsible for completing attribute injection
  • There is a problem to pay attention to in use. If you must make the annotation effective, you need to turn on the annotation support
	<!--Enable annotation support-->
    <context:annotation-config/>
    <!--    Specify the package to be scanned, and the annotations under the package will take effect-->
    <context:component-scan base-package="cn.sdablog"/>

10 configuring Spring in java

10.1 configuring Spring in Java

Configuring Spring in java aims to reduce the xml configuration of Spring, which is all controlled by java

  • Entity class:
public class User {
    private String name;
    public String getName() {
        return name;
    }
    @Value("Zhang San")
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                '}';
    }
}
  • Create a configuration class (this class is equivalent to the bean.xml configuration file):
    1. @ Configuration acts on the class, which is equivalent to an xml Configuration file;
    2. @ Bean acts on methods, which is equivalent to < Bean > in xml configuration;

    Although the java configuration file is equivalent to bean.xml, the java configuration file should use other annotations (@ Component, @ Repository, etc.)

// @Configuration: represents that this class is managed by Spring and has been registered in the container
@Configuration
public class Appconfig {
    // Register a bean, which is equivalent to the bean tag in the bean.xml file
    // Method name = = id name in xml file, return value = = class attribute in xml file
    @Bean
    public User getUser(){
        return new User();
    }
}


If there are multiple configuration classes, you need to Import configuration file 2 into configuration file 1. You can use @ Import to Import the class object of the configuration class

  • Test class
public class MyTest {
    public static void main(String[] args) {
    	// Get the container through the AnnotationConfig context and load it through the class object of the configuration class.
        ApplicationContext context = new AnnotationConfigApplicationContext(Appconfig.class);
        User user = (User) context.getBean("getUser");
        System.out.println(user.getName());
    }
}

10.2 differences between Java configuration, XML configuration and annotation

Features \ configuration modeXMLannotationJava Config
Is the type safeNYY
Is it convenient to find the implementation classN. Need to find all xmlY. Just see which implementation class is annotatedN. All Java configs need to be found
ReadabilityPoor, there are many xml tags, which are not easy to readVery good. Annotation plays the role of annotation at the same timeBetter, for Java programmers, reading java code is more convenient than reading xml
Configuration simplicityVery wordyVery conciseA little wordy
Do you need to recompile to modify the configurationN. Just replace the xml file directlyY. You need to recompile the class file and replace itY. Same as annotation configuration
Will it invade the codeNYN
freedomLow, SPEL syntax can be used, but the functions that SPEL syntax can achieve are limitedLow, can only be configured based on the attribute of the annotationHigh, you can freely use Java syntax and call various functions to inject objects
Can I inject classes that are not maintained by myselfYNY
  • Compared with the other two methods, xml configuration has few advantages. The only advantage is that there is no need to recompile after modification. Therefore, for some objects that often switch implementation classes, xml configuration can be used. In addition, because xml is the configuration method provided by Spring from the beginning, many old codes still use xml, so it is inevitable to use xml when maintaining old codes.
  • Annotations are very concise to use, and the amount of code is very small, so they are the first choice for the project. Java Config is required only when the code to be injected is not the class in the third-party jar package maintained by yourself, or more flexible injection is required. For example, you need to call an interface, query the data, and then assign the data to the object to be injected.

There are three ways to distinguish reference Blogs: https://blog.csdn.net/qq_39331713/article/details/82225056

11. Agency model

Agent: agent is to enhance the original functions without changing the source code

11.1 dynamic agent

  • Dynamic agents are dynamically generated, not written directly

  • Dynamic agents are divided into two categories: 1. Interface based dynamic agents and 2. Class based dynamic agents
    1. Interface based - JDK dynamic agent

    1. Requirement: at least one interface of the proxied class
    2. Provider: JDK official
    3. Involved: Proxy
    4. Method to create proxy object: newProxyInstance
    5. Parameters in method:
      1. ClassLoader: class loader, which is responsible for loading the bytecode of the proxy object. It uses the same class loader (fixed writing method) as the proxy object
      2. Class<?> []: bytecode array, which is responsible for making the production proxy object have the same method as the proxy object. What to write depends on whether the proxy object is an interface or an implementation class;
        1: If it is an interface: new Class [] {interface}
        2: If it is an implementation class: XXX.getClass().getInterfaces() -- this is a fixed writing method
      3. InvocationHandler: an interface. We need to provide the implementation of the interface; The function is to enhance the method; Enhanced code, who uses who writes; Write an interface implementation class; It is usually an anonymous inner class, but it is not absolute.

    2. Subclass based dynamic proxy cglib

    1. Requirement: the coordinates of cglib need to be imported. The proxied class is not the final class (it cannot be modified by final)
    2. Provider: cglib (third party)
    3. Involved: Enhancer
    4. Method for creating proxy object: create
    5. Parameters in method:
      1. Class: bytecode object, used to load bytecode of proxy object; Write the bytecode of the proxy object (fixed writing method);
      2. Callback: how to proxy and provide enhanced code. It is an interface and needs to be written and implemented by yourself;

You need to know two classes:
3. Proxy: proxy
4. InvocationHandler:

11.2 AOP

AOP (Aspect Oriented Programming) means: Aspect Oriented Programming, which realizes the unified maintenance of program functions through precompiled mode and dynamic agent during operation. AOP is the continuation of OOP, a hot spot in software development, an important content in Spring framework, and a derivative paradigm of functional programming. AOP can isolate each part of business logic, reduce the coupling between each part of business logic, improve the reusability of program, and improve the efficiency of development.

spring needs to import packages to use aop:

 <!--   AOP Package support-->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.7</version>
        </dependency>

AOP concept

  • Aspect: modularization of a concern that may crosscut multiple objects. It is a class.
  • Join point: the execution point that matches the pointcut
  • Advice: work that must be completed in all aspects. It is a method in a class.
  • Pointcut: the definition of the place where the aspect notification is executed.
  • Target object: target object
  • AOP proxy: an object created after notification is applied to the target object

Type of advice:

  • Before advice: a notification executed before a Join point, but this notification cannot prevent the execution of the Join point (unless it throws an exception).
  • After returning advice: a notification executed after a Join point completes normally. For example, a method returns normally without throwing any exceptions.
  • After throwing advice: a notification executed after a method throws an exception.
  • After (finally) advice: a notification executed when a Join point exits (whether it returns normally or exits abnormally).
  • Around advice: a notification that surrounds a Join point, such as a method call. This is the most powerful type of notification. Surround notifications can complete custom behavior before and after methods. It also chooses whether to continue execution of join points or directly return their own return values or throw exceptions to end execution.

Method 1: use the Spring API interface

log class:

import org.springframework.aop.MethodBeforeAdvice;
import java.lang.reflect.Method;
public class Log implements MethodBeforeAdvice {
    /**
     * method:Method of the target object to execute
     * objects: parameter
     * o: Target object
     */
    @Override
    public void before(Method method, Object[] objects, Object o) throws Throwable {
        System.out.println(o.getClass().getName() + " of " + method.getName() + " Executed!");
    }
}

afterlog class:

import org.springframework.aop.AfterReturningAdvice;
import java.lang.reflect.Method;
public class AfterLog implements AfterReturningAdvice {
    /**
     * returnValue:Return value result
     * method: Method of the object to execute
     * args: parameter
     * target: Target object
     */
    @Override
    public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
        System.out.println("Object:" + target.getClass().getName() + "Method implemented:" + method.getName() + " The return value is:" + returnValue);
    }
}

applicationContex.xml

<?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:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd">

    <!--register bean-->
    <bean id="userService" class="cn.sdablog.service.UserServiceImpl"/>
    <bean id="log" class="cn.sdablog.log.Log"/>
    <bean id="afterlog" class="cn.sdablog.log.AfterLog"/>
    <!--Method 1: use native Spring API Interface
        to configure aop:Import aop Constraints of-->
    <aop:config>
        <!-- breakthrough point
             expression: breakthrough point
             execution(Location to execute. * * * * *): Method is filled with the position to be executed, with 5 parameters
        -->
        <aop:pointcut id="pointcuts" expression="execution(* cn.sdablog.service.UserServiceImpl.*(..))"/>
        <!-- Execute surround increase
             advice-ref:Application template
             pointcut-ref: Entry point (when to execute)
        -->
        <aop:advisor advice-ref="log" pointcut-ref="pointcuts"/>
        <aop:advisor advice-ref="afterlog" pointcut-ref="pointcuts"/>
    </aop:config>
</beans>

Test class:

import cn.sdablog.service.UserService;
import cn.sdablog.service.UserServiceImpl;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest1 {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        // Dynamic proxy is the interface class
        UserService userservice = context.getBean("userService", UserService.class);
        userservice.add();
    }
}

Output results:

Method 2: custom implementation

DiyPoincut class:

// Custom aop 
public class DiyPoinCut {
    public void before(){
        System.out.println("==================Before method execution===============");
    }
    public void after(){
        System.out.println("==================After method execution===============");
    }
}

applicationContex.xml

<?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:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd">

    <!--register bean-->
    <bean id="userService" class="cn.sdablog.service.UserServiceImpl"/>
	<!-- Method 2: user defined class-->
    <bean id="diy" class="cn.sdablog.diy.DiyPoinCut"/>
    <aop:config>
        <aop:aspect ref="diy">
            <!-- breakthrough point-->
            <aop:pointcut id="point" expression="execution(* cn.sdablog.service.UserServiceImpl.*(..))"/>
            <!-- notice-->
            <aop:before method="before" pointcut-ref="point"/>
            <aop:after method="after" pointcut-ref="point"/>
        </aop:aspect>
    </aop:config>
</beans>

Test class:

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest1 {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        // Dynamic proxy is the interface class
        UserService userservice = context.getBean("userService", UserService.class);
        userservice.add();
    }
}

Output results:

11.3 implementing AOP with annotations

  1. applicationContext.xml configuration:
    Need to open AOP annotation support (AOP auto proxy AspectJ AutoProxy)
<?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:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd">

    <!--register bean-->
    <bean id="userService" class="cn.sdablog.service.UserServiceImpl"/>
    <bean id="log" class="cn.sdablog.log.Log"/>
    <bean id="afterlog" class="cn.sdablog.log.AfterLog"/>
    <!-- Method 3: annotation use AOP-->
    <bean id="diypoinCut1" class="cn.sdablog.diy.DiyPoinCut1"/>
    <!-- open AOP Annotation support-->
    <aop:aspectj-autoproxy/>
</beans>

diypoinCut1 class:

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

//Label this class as a facet
@Aspect
public class DiyPoinCut1 {
    @Before("execution(* cn.sdablog.service.UserServiceImpl.*(..))")
    public void befor(){
        System.out.println("======Before method execution======");
    }
    @After("execution(* cn.sdablog.service.UserServiceImpl.*(..))")
    public void after(){
        System.out.println("======After method execution======");
    }
    //Surround enhancement
    @Around("execution(* cn.sdablog.service.UserServiceImpl.*(..))")
    public void around(ProceedingJoinPoint pj) throws Throwable {
        System.out.println("Surround front");
        Object proceed = pj.proceed();
        System.out.println("After surround");
    }
}

Test class:

import cn.sdablog.service.UserService;
import cn.sdablog.service.UserServiceImpl;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest1 {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        // Dynamic proxy is the interface class
        UserService userservice = context.getBean("userService", UserService.class);
        userservice.add();
    }
}

Output results:

Tags: Java Spring ioc

Posted on Sun, 19 Sep 2021 07:45:05 -0400 by tefflox