Spring Framework Knowledge Summary IOC\DI Pure Annotation DevelopmentAOP

Keywords: Java Spring

The Spring Framework is the most basic project in the Spring Ecosphere and the foundation of other projects

1: Core container:

Spring containers are the core of the Spring framework and are used to manage objects. Containers create objects, connect them together, configure them, and manage their entire life cycle from creation to destruction.

What kind of objects to put in the container:

  • dao class
  • service class
  • controller class
  • Tool class
    What kind of objects do not fit into container objects?
  • servlet class, listener,filter class
  • Entity bean classes (because they need to be dynamically fetched from the database)

IOC Control Reverse

Controlling Inverse IOC is an idea and a concept that refers to the creation, assignment, and management of objects to containers outside of code.That is, the creation of objects is done by other external resources. Understanding? In fact, the TomCat server we use reflects this idea: we just registered the servlet in the web.xml file using the servlet tag, and we didn't do any newServlet's operation, so the Servlet was created by the TomCat server, so TomCat is also called a container, but the TomCat container contains Servlet objects, Listener s, Filter objects
How do you create objects from the Spring container implementation?
(1) Join Spring dependency

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.4</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
    </dependencies>

(2) Add interfaces and implementation classes for testing and write a test method for testing
(3) Configure the Spring configuration file ApplicationContext.xml under the resources directory of the project, where the bean tag defined is the object that you want Spring to create

<?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">
    <!--statement bean,Is to tell spring Object to create a class
    id:Custom name of object,Unique Value,spring Find the object by this name
    class:Fully qualified name of class(Cannot be an interface,because spring Creating objects through a reflection mechanism,Classes must be used)-->
    <bean id="OneService" class="icu.not996.service.servoiceImpl.OneServiceImpl"/>
    <!--This statement means Spring It's done OneService oneService=new OneServiceImp
    Spring Is to put the created object in map In collection Spring One of them map Collections are used to store objects
    Be similar to:
        springMap.put(id Value of,object);
    example: springMap.put("OneServiceImpl",new OneServiceImpl());
    One bean Label declares a java object
    -->
</beans>

(4) Creating objects using Spring

@Test
public void TestSpring01(){
    //Creating objects using the Spring container
    //1. Specify the name of the Spring profile
    String config="ApplicationContext.xml";
    //2. Create an object representing the Spring container, ApplicationContest
    //An ApplicationContext represents a Spring container in which objects are used through container objects
    //ClassPathApplicationContext() indicates that the Spring configuration file is documented through the class path
    ApplicationContext ac=new ClassPathXmlApplicationContext(config);
    //Get the object you want from the container and call the method you want to call
    OneService oneService = (OneService) ac.getBean("OneService");
    //Objects created with Spring
    oneService.doSome();
}

By running we can see that we are not actively going to the new OneServlet object, but we can get it

DI

Grammatical classification of di:

1.setter injection (set value injection)

Spring calls the class's construction method, which enables assignment of attributes in set methods, 80% of which use set injection
Basic data types are injected directly using the value attribute:

<bean id="" class="">
    <property name="name" value="Zhang San" />
    <property name="age" value="1" />
 </bean>

Reference data types are introduced using the ref attribute:

<bean id="mySchool" class="icu.not996.ba02.School">
    <property name="name" value="Chengbei Primary School"/>
    <property name="address" value="Heze Cao County, Shandong Province"/>
</bean>
<!--Reference Type set injection:Spring Calling class set Method
 grammar:
<bean id="xxx" class="yyy">
    <property name="Property Name" ref="bean Of id(Name of object)"/>
</bean>
-->
<bean id="myStudent" class="icu.not996.ba02.Student">
    <property name="name" value="Xiaohua"/>
    <property name="age" value="8"/>
    <property name="school" ref="mySchool"/>
</bean>

2. Construction Injection

Spring calls the class's parametric construction method to create the object. Complete the assignment in the construction method
Represents a parameter in a construction method
Label properties:
Name:The name of the formal parameter that represents the construction method
index: Represents the position of the parameters of the construction method, the order in which the parameters are 0,1,2 from left to right
Value: The parameter type of the construction method is simple, using value
Ref: The parameter type of the constructor is the use of ref for the reference type

<!--Use name Property Implementation Construction Injection-->
<bean id="MySchool" class="">
    <constructor-arg name="address"  value="Heze Cao County, Shandong Province"/>
    <constructor-arg name="name"  value="Chengbei Middle School"/>
</bean>

<bean id="oneStudent" class="">
    <constructor-arg name="age" value="10"  />
    <constructor-arg name="name" value="Xiaohua" />
    <constructor-arg name="school"  ref="MySchool"/>
</bean>

3. Automatic Injection of Reference Types

The Spring Framework can assign reference types based on certain rules and does not need to assign reference types manually. It can only be a reference type, not a basic data type
Rule Name for automatic injection: usually byName and byType
byName: Injected by name, beans in a java class that refer to the same property name as the id name in the Spring container (configuration file) and have the same data type, spring can be assigned to reference types
Grammar:

Assignment of simple types

bytType: Inject by type: Reference types in java classes and class attributes in spring containers (configuration files) are homologous, and such bean s can be assigned to reference types
Homology: The same category means:
1. The data type of the reference type in the Java class is the same as the class value in the bean
2. The data type of the reference type in the Java class and the class value of the bean are parent-child class relationships
3. The data type of the reference type in the Java class and the class value of the bean are the relationship between the interface and the implementation class

2: Developing Spring with pure annotations

Developing Spring using pure annotations further simplifies the development of the Spring framework
First, let's look back at what Spring's configuration file ApplicationContext.xml did: it tells the framework where the Bean is located and injects attribute values into it
Spring also provides annotated ways to do these things:

(1) Initialize a Spring configuration class

First, the annotations are written above the classes and methods, so we need to write a Spring configuration class, SpringConfig:
Use the @Configuration annotation to tell Spring that I am a Spring configuration class

@Configuration  //This annotation indicates that this class is a Spring configuration class
public class SpringConfig {
}

(2) How do I create bean s in containers?

Spring provides four notes:

  • @Component is used to create a Bean in a container
    Spring also provides three derived annotations for the @Componment annotation, which are the same functionality and can be used to create different bean objects
  • bean Definition for Presentation Layer by @Controller
  • @Service bean Definition for Business Tier
  • @Repositiory bean Definition for Data Layer
    Example:
@Repository("bookDao")   //The value property of the comment is equivalent to using the id in the configuration file
public class BookDaoImpl implements BookDao {
    String userName;
    String some;
    public void show() {
        System.out.println("BookDaoImpl show() run ~"+userName+"---"+some);
    }
}  //Code is meaningless, only for test reference

But how does Spring know where to load these annotations? Scan them all once? So you should specify the packages that need to load bean s in the Spring configuration class
Using the @ComponentScan annotation, you can pass in an array in the following format:

@Configuration
@ComponentScan({"icu.not996.dao.impl","icu.not996.service.impl"})
public class SpringConfig {
}

(3) How to set up dependency injection using annotation development?

Basic data type @Value annotation

@Repository("bookDao")
public class BookDaoImpl implements BookDao {
    @Value("ZhangMeiyu")
    String userName;
    @Value("Northeast Warlord")
    String some;
    public void show() {
        System.out.println("BookDaoImpl show() run ~"+userName+"---"+some);
    }
}

However, this will result in strong program coupling and difficult to modify attribute values, so we will use the configuration file to optimize:

Introducing profile content

(1) Write a configuration file: bookDao.properties
The content is:
dao.username=ZhangMeiyu
dao.some = Northeast Warvalve
(2) Tell Spring where this profile is located:
Annotate the Spring Config configuration class:
@PropertySource({"dao.properties"})//can be in the form of an array and can write multiple
(3) Use ${"key"} in your code to reference the value in the configuration file

    @Value("${dao.username}")
    String userName;

Reference data type @Autowired comment

@Autowired is roughly the same as @Value, except @Autowired defaults to ByType being automatically injected by type
If there are multiple identical types in the container that will pass through ByName, this is done by adding another comment under the @Autowired comment: @Qualifier(")

@Service("bookService")
public class BookServiceImpl implements BookService {
    @Autowired()
    @Qualifier("bookDao")
    BookDao bookDao;
    ......
}

(4) Manage third-party beans using Spring

In development, we often talk about putting third-party developed Bean objects in containers. What can we do about this? We can't always add @Component to the third-party source code.
For example, we're going to put DataSource interface implementation class objects in containers that we can use over time
Spring certainly has solutions for us:
@Bean comment
Implementation method:
(1) Write a separate configuration class first
(2) Write a method in which the return value is the type of bean that needs to be created in the container
(3) Add @Bean comment to the method
(4) Assigning values to the attributes of the object:
Basic data types:
Extract a property as a member variable and assign it a value using the @Value property in the member variable
Reference data type:
The method of referencing a data type is special, and the reference data type that needs to be injected is written at the row parameter location of the method
(5) Create the property object in the method, then call Set method to set the property of the object.

public class JdbcConfig {
    @Value("jdbc.driverClassName")
    private String druidDataSource;
    @Value("jdbc.url")
    private String driverClassName;
    @Value("jdbc.username")
    private String userName;
    @Value("jdbc.password")
    private String password;
    @Bean
    public DataSource dataSource(BookService bookService1){
        bookService1.show();
        DruidDataSource dds=new DruidDataSource();
        dds.setDriverClassName(druidDataSource);
        dds.setUrl(driverClassName);
        dds.setUsername(userName);
        dds.setPassword(password);
        return dds;
    }
}

3. AOP

1. Concepts

Understanding face-oriented programming:

(1) Find facets when analyzing projects
(2) Reasonably schedule the execution time of the tangent (before or after the target method)
(3) Reasonably arrange the execution location of the tangent, in which class and method to add functions

AOP(Aspect Orient Programming), Face-Oriented Programming, Face-Oriented Programming is a dynamic view of the program's running process
AOP Bottom Level: Implemented by Dynamic Proxy mode, using two proxies: JDK Dynamic Proxy and CGLIB Dynamic Proxy
AOP is the normalization of dynamic agents. It defines the implementation steps of dynamic agents so that developers can use dynamic agents in a unified way.

aop action:

(1) Add functionality without modifying the source code of the target class
(2) Reduce duplicate code
(3) Focus on the implementation of business functions
(4) Decoupling: decoupling mainly business and non-business functions (logs, transactions)

When to consider using aop technology:

(1) When you want to give a copy of the class modification function that exists in the system, but the original class function is not perfect, you have no source code, you can only add functions through AOP.
(2) To add the same functionality to multiple classes in a project, use aop
(3) Add transactions and log output to methods using aop

AOP(Aspect Orient Programming), Face Oriented Programming
Aspect: Aspect, an added feature to your target class, is Aspect, where operations like logging committed transactions are Aspect
Features of facets: generally independent of business methods, non-business methods, can use functions independently
Orient:Programming Oriented:Programming

Terminology:

(1)Aspect: Aspect: Aspect, which represents enhanced functionality, is a stack of code that completes a function, typically a non-business function
Common facet functionality: logging, transactions, statistics, parameter checking, permission validation
(2)JoinPoint: The connection point, the location where business methods and facets are connected, is the business method in a class in Spring AOP
(3)Pointcut: A point of entry, a collection of multiple connection point methods that incorporate facet functionality.
(4) Target object: To which class to add functionality, this class is the target object
(5)Advice: Notification indicates when the slicing function is executed

2. Implement AOP

1.Spring:Spring implements the aop specification internally and does the work of aop (implemented by interfaces)
Spring uses aop primarily for transactional purposes
Spring's aop implementation is rarely used in our project development because aop in Spring is cumbersome
2.AspectJ: An open source, aop-specific framework from the Eclipse Open Source Foundation
AspectJ is an excellent facet-oriented framework that extends the Java language and provides a powerful facet implementation
AspectJ is integrated into the Spring framework and its functionality is available through Spring
Because of AspectJ's excellence, Spring embraces AspectJ to implement AOP, so it needs to import AspectJ's dependencies first

(1) Add AspectJ dependencies

        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.4</version>
        </dependency>

(2) Notification class

Notifications are a method and cannot exist alone, so a notification class is needed in which to write the notification method:
The first notification class needs to be loaded by Spring, so the notification class needs to be annotated: @Component
Notification class also needs to tell Spring: I'm a notification class! So I need to add a comment: @Aspect

@Component  //This comment is for spring to load it (to be within the scope of the SpringConfig comment@ComponentScan scan)
@Aspect   //This comment tells spring that this class is a notification class, tells spring to treat me as an aop after scanning me
public class MyAdvice {......}

Spring can't load these annotations at this time, so tell Spring that I have an AOP developed with annotations that you need to know about, so you also need to annotate the SpringConfig class:

@EnableAspectJAutoProxy  //Tell the program that it was an aop developed with annotations

There are two methods in the notification class:
(1) Private shell methods: Used to define entry points, that is, to specify which method you want to add functionality to, which do not implement any functionality
Add the comment @PointCut(") comment to the method where you write your entry point expression

Entry point expression

The standard format is action keyword (access modifier return value package name, class/interface name, method name (parameter name) exception name)

  • Action keywords typically use execution to indicate execution to a specified entry point
  • Access modifiers and exception names can be omitted
  • *Represents any symbol, either individually or matching package/class/method names
  • For example: execution (public * com.it1k..UserService.find (*))
  • ... denotes a continuous, arbitrary symbol that can appear independently and is often used to simplify the writing of package and parameter names, for example, to denote any parameter/any return value type
  • +: Specially designed to match subclass types
  • For example: execution(* *... Service+. (...)) represents any method of any Service subclass
    (2) Notification method: extracting the common functions required by the entry point
    @Pointcut("execution(* icu.not996.dao.BookDao.save (..))")  //Match save methods in BookDao
    private void pt(){     //Private method, shell method, responsible for defining where notifications are executed
    }
AOP Notification Type

AOP notifications describe the common functionality of the extract and, depending on where it is extracted, add it to a reasonable location when the code is finally run
Pre-Notification@Before before entry point code execution
Post-notification: @After entry point code after execution
Before and after execution of surround notification@Arround entry point code
Notify @AfterReturning entry point method after returning value result
After throwing an exception @AfterThrowing entry point method after throwing an exception
The value attribute of the above comment needs to be populated with the private method name above to indicate where to execute

   //Specify an execution time to execute before the entry point
    @Around(value = "pt()")
    public Object method1(ProceedingJoinPoint pjp){.....}

The notification type after the method has started running gets the method's incoming parameters, and the parameters can be checked after the original method's parameters have been obtained by adding an object JoinPoint at the method's parameter position, if the surround notification is its subclass ProceedingJoinPoint (because the surround notification specifies when to run the original method).
The @AfterRunning and @AfterThrowing and @Arround annotations get the return value of the method, and do some work on the return value before returning it, which needs to be used on the parameters of the annotation
returning specifies the return value, which can then be written at the method's parameter location for internal operation
Give an example:

    @AfterReturning(value="ptDel()",returning = "rtv")
    public Object afterReturning(JoinPoint pjp,Object rtv) throws Throwable {
        Object[] args = pjp.getArgs();
        Arrays.stream(args).forEach(arg-> System.out.println("Method parameter is:"+arg));
        System.out.println(rtv.toString()+"Bar data deleted");
        return rtv;
    }

Surround notification example:

    @Around(value = "pt()")
    public Object method1(ProceedingJoinPoint pjp) throws Throwable {
        Signature signature = pjp.getSignature();
        Object[] args = pjp.getArgs();//Get the parameters of the original method
        if(("Self-cultivation of high-quality men").equals(((Book)(args[0])).getName())){ //Parameter Check
            ((Book)(args[0])).setName("Human oil");//Modify the value of the original data so that the incoming value is executed directly by default
        }
        System.out.println("System time before program execution is:"+System.currentTimeMillis());//Add Notification
        Object proceed = pjp.proceed(args);//Run the original method and get the return value of the original method
        if(Integer.parseInt(proceed.toString())>0){
            System.out.println("Data added successfully");
        }else{
            System.out.println("Data addition failed");
        }
        return Integer.parseInt(proceed.toString());//Processing the return value of the original method and returning it
    }

So surround notifications are still powerful, enabling four other notifications

Posted by cosminb on Wed, 08 Sep 2021 17:14:00 -0700