Spring Framework 01 IOC AOP

This section covers all the technologies that are absolutely integral to the Spring Framework. Foremost among these is the Spring Framework's Inversion of Control (IoC) container, closely followed by comprehensive coverage of Spring's Aspect-Oriented Programming (AOP) technology. Spring Framework has its own AOP framework, which is conceptually easy to understand.

Inversion of Control (IoC)

Introduction to Spring IoC Containers and Beans

IoC, also known as dependency injection (DI), is the process by which objects are passed only to constructor parameters, parameters to factory methods, or properties that are set after an object instance is constructed or returned from a factory method. The container then injects these dependencies when creating the bean. The process is basically reversed (hence the name, inversion of control). The bean itself controls the instantiation or location of its dependencies by using mechanisms such as direct construction of the class or the service locator pattern.

org.springframework.beansThe and org.springframework.contextpackage is the basis for the Spring Framework's IoC container. BeanFactoryThe interface provides an advanced configuration mechanism capable of managing any type of object, provides a configuration framework and basic functions, and ApplicationContextadds more enterprise-specific functions.

In Spring, the objects that form the backbone of an application and are managed by the Spring IoC container are called beans. A bean is an object instantiated, assembled, and managed by the Spring IoC container. Otherwise, the bean is just one of many objects in the application. Beans and the dependencies between them are reflected in the configuration metadata used by the container.

container overview

org.springframework.context.ApplicationContextThe interface represents the Spring IoC container responsible for instantiating, configuring and assembling beans. Containers get instructions about which objects to instantiate, configure, and assemble by reading configuration metadata. Configuration metadata is expressed in XML, Java annotations, or Java code. It lets you express the objects that make up your application and the rich interdependencies between those objects.

Spring provides several implementations of ApplicationContextthe interface . In a stand-alone application, it is common to ClassPathXmlApplicationContextcreate FileSystemXmlApplicationContextinstances of or .

The diagram below shows how Spring works. Your application classes are combined with configuration metadata, so after the ApplicationContext is created and initialized, you have a fully configured and executable system or application.

container-magic

Configuration Metadata

The following example shows the basic structure of XML-based configuration metadata

<?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
        https://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="..." class="...">  
        <!-- collaborators and configuration for this bean go here -->
    </bean>
    <bean id="..." class="...">
        <!-- collaborators and configuration for this bean go here -->
    </bean>
    <!-- more bean definitions go here -->
</beans>
  • idattribute is a string identifying a single bean definition

  • classThe property defines the type of the bean and uses the fully qualified class name

instantiate a container

One or more location path resource strings provided to the ApplicationContextconstructor , which allow the container to load configuration metadata from various external sources (such as the local file system, Java CLASSPATH, etc.)

ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");
<!--service.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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">
    <!-- services -->
    <bean id="petStore" class="org.springframework.samples.jpetstore.services.PetStoreServiceImpl">
        <property name="accountDao" ref="accountDao"/>
        <property name="itemDao" ref="itemDao"/>
        <!-- additional collaborators and configuration for this bean go here -->
    </bean>
    <!-- more bean definitions for services go here -->
</beans>

use container

ApplicationContextIs an interface to a high-level factory capable of maintaining a registry of different beans and their dependencies. By using a method T getBean(String name, Class<T> requiredType), an instance of a bean can be retrieved.

// create and configure beans
ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");
// retrieve configured instance
PetStoreService service = context.getBean("petStore", PetStoreService.class);
// use configured instance
List<String> userList = service.getUsernameList();

Bean overview

The Spring IoC container manages one or more beans. These beans are created using configuration metadata that you provide to the container (for example, in <bean/>the form of an XML definition).

Within the container itself, these bean definitions are represented as BeanDefinition objects, which contain (among other information) the following metadata:

  • A package-qualified class name: usually the actual implementation class of the bean being defined

  • Bean behavior configuration elements, which describe how the bean behaves in the container (scope, lifecycle callbacks, etc.)

  • References to other beans that the bean needs to perform its work. These references are also known as collaborators or dependencies

  • Additional configuration settings to be set in the newly created object

naming beans

Every bean has one or more identifiers. These identifiers must be unique within the container hosting the bean. A bean usually has only one identifier. In XML-based configuration metadata, you idcan namespecify bean identifiers using attributes, attributes, or both. idattribute allows you to specify one id. Bean id uniqueness is still enforced by the container, but no longer by the XML parser.

Instantiate the bean

A bean definition is essentially a way to create one or more objects. When asked, the container looks at the named bean's methods and uses the configuration metadata encapsulated by that bean definition to create (or obtain) the actual object.

dependency injection

Dependency Injection (DI) is a process in which objects define their dependencies (that is, other objects with which they work) only through constructor parameters, parameters of factory methods, or properties of object instances that are set upon or after construction, Return from factory method. The container then injects these dependencies when creating the bean. This process is basically the inverse of the bean itself (hence the name, inversion of control), controlling the instantiation or location of its dependencies itself by using direct construction of the class or the service locator pattern.

Aspect Oriented Programming (AOP)

Aspect-Oriented Programming (AOP) complements Object-Oriented Programming (OOP) by providing another way of thinking about program structure. The key unit of modularity in OOP is the class, while the unit of modularity in AOP is the aspect. Aspects enable the modularization of concerns (such as transaction management) across multiple types and objects. (Such concerns are often referred to as "crosscutting" concerns in the AOP literature)

One of the key components of Spring is the AOP framework. Although the Spring IoC container does not depend on AOP (meaning you don't need to use AOP if you don't want to), AOP complements Spring IoC to provide a very powerful middleware solution.

AOP concepts

  • Aspects: Modularization of concerns that span multiple classes. Transaction management is a good example of a cross-cutting concern in an enterprise Java application. In Spring AOP, aspects are implemented by using regular classes (pattern-based approach) or regular classes annotated with the @Aspect annotation.
  • Weaving: Linking aspects with other application types or objects to create advice objects. This can be done at compile time (eg using the AspectJ compiler), load time or runtime. Spring AOP, like other pure Java AOP frameworks, performs weaving at runtime.

Spring AOP capabilities and goals

Spring AOP's approach to AOP is different from most other AOP frameworks. The goal is not to provide the most complete AOP implementation (although Spring AOP is very capable). Instead, the intent is to provide tight integration between AOP implementations and Spring IoC to help solve common problems in enterprise applications.

example

Refer to how2j 's tutorial and use Idea to complete

build project

Create a new normal maven project and introduce dependencies

<!-- pom.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.wjl</groupId>
    <artifactId>spring-how2j</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>spring-how2j-01-IOC</module>
        <module>spring-how2j-02-Inject</module>
        <module>spring-how2j-03-annotation-ioc</module>
        <module>spring-how2j-04-aop</module>
        <module>spring-how2j-05-annotation-aop</module>
    </modules>
    <properties>
        <maven.compiler.source>16</maven.compiler.source>
        <maven.compiler.target>16</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.hamcrest</groupId>
            <artifactId>hamcrest</artifactId>
            <version>2.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.3.9</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.20</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.3.9</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.3.9</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.2</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.7</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.7</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>2.0.6</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.25</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.batch</groupId>
            <artifactId>spring-batch-core</artifactId>
            <version>4.3.3</version>
        </dependency>
    </dependencies>

</project>

Right-click the project, select New Module, and create a new ordinary maven project as a subproject of the project just created, without repeatedly importing dependencies.

image-20210724203519623

IOC

Create a new subproject spring-how2j-01-IOC, create Categoryan Productentity class

// Category.java
public class Category {
    
    
    private int id;
    private String name;
}
// Product.java
public class Product {
    
    
    private int id;
    private String name;
    private Category category;
}

Create a spring configuration file in resourcesthe directory applicationContext.xmland inject two entity classes

<?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-3.0.xsd">
    <bean name="c" class="com.wjl.pojo.Category">
        <property name="name" value="category 1"/>
    </bean>
    <bean name="p" class="com.wjl.pojo.Product">
        <property name="id" value="3"/>
        <property name="name" value="Product 1"/>
        <property name="category" ref="c"/>
    </bean>
</beans>

Create a new test class, use the spring container to create an entity class, and print out the class properties

public class TestSpring {
    
    
    @Test
    public void test() {
    
    
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        Category c = (Category) context.getBean("c");
        System.out.println(c.getName());
        Product p = (Product) context.getBean("p");
        System.out.println(p.toString());
    }
}

insert image description here

AOP

Yes Category, Productthe entity class uses the annotation method to inject the spring container

@Component("c")
public class Category {
    
    
    private int id;
    private String name;
}
@Component("p")
public class Product {
    
    
    private int id;
    private String name;
    private Category category;
}

ProductWrite a simple service layer for

// ProductService.java
public interface ProductService {
    
    
    void addProduct();
    void deleteProduct();
    void updateProduct();
    void searchProduct();
}
// ProductServiceImpl.java
@Component("s")
public class ProductServiceImpl implements ProductService {
    
    
    @Override
    public void addProduct() {
    
     System.out.println("add a product"); }
    @Override
    public void deleteProduct() {
    
     System.out.println("delete a product"); }
    @Override
    public void updateProduct() {
    
     System.out.println("update products"); }
    @Override
    public void searchProduct() {
    
     System.out.println("search all products"); }
}

Create a new log section LoggerAspect.javato output service call time and count service running time

package com.wjl.aspect;
public class LoggerAspect {
    public Object log(ProceedingJoinPoint joinPoint) throws Throwable {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date begin = new Date();
        System.out.println("[" + simpleDateFormat.format(begin) + " start log] " + joinPoint.getSignature().getName());
        long a = System.currentTimeMillis();
        Object object = joinPoint.proceed();
        long b = System.currentTimeMillis();
        Date end = new Date();
        System.out.println("[" + simpleDateFormat.format(end) + " end log] " + joinPoint.getSignature().getName());
        System.out.println("it costs " + (double)(b - a) / 1000 + " s");
        return object;
    }
}

Configure the spring configuration file

<?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"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    <context:component-scan base-package="com.wjl.pojo"/>
    <context:component-scan base-package="com.wjl.service"/>
    <bean id="loggerAspect" class="com.wjl.aspect.LoggerAspect"/>
    <aop:config>
        <aop:pointcut id="loggerCutpoint" expression="execution(* com.wjl.service.ProductService.*(..))"/>
        <aop:aspect id="logAspect" ref="loggerAspect">
            <aop:around pointcut-ref="loggerCutpoint" method="log"/>
        </aop:aspect>
    </aop:config>
</beans>

Create test class

public void test() {
    
    
    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    ProductService s = (ProductService) context.getBean("s");
    s.addProduct();
    s.searchProduct();
}

insert image description here

All running results

  1. Spring IOC/DI

insert image description here

  1. Spring injection object

insert image description here

  1. Spring annotation method IOC/DI

insert image description here

  1. Spring AOP

insert image description here

  1. Spring annotation method AOP

insert image description here

  1. Spring annotation test

insert image description here

Summarize

Spring's IOC and AOP have greatly improved the efficiency of development, but the program relies too much on the configuration file. If the configuration file is wrong, there will be no obvious prompts like the program writing error. Often, the program will not run because of the wrong configuration file, which is worthy of the name. Configuration hell.

Spring has condensed the wisdom of many programmers. The tutorials on the how2j website are relatively simple and do not touch on deeper content. You need to bite the bullet and read the official documents to learn more.

Guess you like

Origin blog.csdn.net/wji15/article/details/126649764