Spring framework (2-1): spring 5 basic IOC / AOP

CodingALife 2022-01-26 16:10:26 阅读数:777

spring framework 2-1 spring basic

Catalog

0、 Write it at the front

1、Spring The framework outlined

2、IOC Containers

2.1、IOC Concepts and principles :

2.2、IOC operation Bean management ( be based on xml)

IOC operation Bean management (FactoryBean)

Bean Scope of action :

Bean Life cycle of :

xml Automatic assembly ( Rarely used , It's usually annotated ):

Operate through the external properties file bean:

2.3. IOC operation Bean management ( Based on annotations )

(1) Create objects based on annotations :

(2) Attribute injection based on annotation :

(3) Fully annotated development :

3、AOP

3.1. Underlying principle

3.2. be based on AspectJ Realization AOP operation

(1) Based on annotation

(2) be based on xml The way


0、 Write it at the front

This article is after learning b Standing in Silicon Valley Spring5 Notes taken , I hope that's helpful !

1、Spring The framework outlined

  • Spring It's lightweight, open source JavaEE frame
  • Spring It can solve the complex problem of enterprise application development
  • Spring There are two core parts :IOC and Aop
    • (1)IOC: Inversion of control , Give the process of creating objects and calling between objects to Spring Conduct management
    • (2)Aop: Face to face , Do not modify the source code to enhance functionality
  • Spring characteristic :
    • Easy decoupling , Simplify the development
    • Aop Programming support
    • Convenient program testing
    • Easy to integrate with other frameworks
    • Convenient for transaction operation
    • Reduce API Development difficulty

2、IOC Containers

2.1、IOC Concepts and principles :

1、 Concept : Inversion of control , Give the process of object creation and object call to spring Conduct management .

2、 Purpose : Reduce coupling .

3、 Underlying principle :xml analysis , Reflection , Factory mode .

Just modify the factory class

Just modify the configuration file :

4、Spring Provide IOC Container can be implemented in two ways ( Two interfaces )

  • BeanFactory:Spring Interfaces used internally , Developers are not encouraged to use .
    • characteristic : No objects are created when the configuration file is loaded , The object is created only when the object is obtained .
  • **ApplicationContext:**BeanFactory Sub interface of , Provides more and more powerful functions , Generally used by developers .
    • characteristic : When loading the configuration file, the objects in the configuration file will be created . Generally, the time-consuming process is completed when the system is started , Reduce web The time of service . Daily use .

5、ApplicationContext Two common implementation classes :

  • FileSystemXmlApplicationContext: Absolute path , Starting from the drive letter
  • ClassPathXmlApplicationContext: Relative paths , from src From the beginning

image-20210720000922536

 6、 What is? Bean management ?

  • Bean Management refers to two operations :Spring Create objects and Spring Injection properties .
  • Bean There are two ways to manage : be based on xml Configuration file mode and Implement based on annotation .

2.2、IOC operation Bean management ( be based on xml)

xml Realization Bean management :
(1) be based on xml How to create objects :

image-20210719101725911

  • stay Spring Use in profile bean Tags to create objects
  • bean Tags have many properties , Common properties :
    • id: Unique identification
    • class: Class path
  • When you create an object , By default, the parameterless constructor is executed

(2) be based on xml Mode injection attribute : 

The first method : Use set Method to inject :

First, provide... For the properties of the class set Method :

public class User {
private String userName;
private String userAge;
public void setUserName(String userName) {
this.userName = userName;
}
public void setUserAge(String userAge) {
this.userAge = userAge;
}
public String getUserName() {
return userName;
}
public String getUserAge() {
return userAge;
}
}

And then in xml Passed in configuration file property Tag for attribute Injection

 <!-- To configure User object -->
<bean id="user" class="com.oymn.spring5.User">
<property name="userName" value="haha"></property>
<property name="userAge" value="18"></property>
</bean>

That's it

 ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean1.xml");
User user = applicationContext.getBean("user", User.class);
System.out.println(user.getUserName() + " " + user.getUserAge());

The second method : Use a parameterized constructor to inject

First, a parametric construction method is provided

public class User {
private String userName;
private String userAge;
public User(String userName, String userAge){
this.userName = userName;
this.userAge = userAge;
}
}

And then again xml Passed in configuration file constructor-arg Tag for attribute Injection

 <!-- To configure User object -->
<bean id="user" class="com.oymn.spring5.User">
<constructor-arg name="userName" value="haha"></constructor-arg>
<constructor-arg name="userAge" value="18"></constructor-arg>
</bean>

The third method :p Namespace injection ( Understanding can )

First, in the xml Add... To the configuration file p The name space , And in bean Operate in the tag

image-20210719104230761

  And then provide the set Method

public class User {
private String userName;
private String userAge;
public User() {
}
public void setUserName(String userName) {
this.userName = userName;
}
public void setUserAge(String userAge) {
this.userAge = userAge;
}
}

(3)xml Inject other attributes

1、null value

 <!-- To configure User object -->
<bean id="user" class="com.oymn.spring5.User">
<property name="userName"> <null/> </property>
</bean>

2、 Attribute values contain special symbols

Suppose now userName Property needs to be assigned to < haha >

If you are directly in value An error will be reported if it is stated in , Because it contains special symbols <>

image-20210720003501206

  Need to pass through  <![CDATA[ value ]]>  To express

image-20210720003720138

 3、 Injection properties —— external bean

There are two classes :UserService and UserDaoImpl, among UserDaoImpl Realization UserDao Interface

public class UserService {
private UserDao userDao;
public void setUserDao(UserDao userDao){
this.userDao = userDao;
}
public void add(){
System.out.println("add");
}
}

adopt ref To specify the creation of userDaoImpl

<bean id="userDaoImpl" class="com.oymn.spring5.UserDaoImpl"></bean>
<bean id="userService" class="com.oymn.spring5.UserService">
<property name="userDao" ref="userDaoImpl"></property>
</bean>

4、 Injection properties —— Inside bean

Not through ref attribute , But by nesting a bean Tag implementation

<!-- Inside bean-->
<bean id="emp" class="com.atguigu.spring5.bean.Emp">
<!-- Set two common properties -->
<property name="ename" value="lucy"></property>
<property name="gender" value=" Woman "></property>
<!-- Set object type properties -->
<property name="dept">
<bean id="dept" class="com.atguigu.spring5.bean.Dept">
<property name="dname" value=" Security Department "></property>
</bean>
</property>
</bean>

5、 Injection properties —— Cascade assignments

Writing a : That is, the external bean, adopt ref Property to get the external bean

Write two :emp There are ename and dept Two attributes , among dept Yes dname attribute , Writing 2 requires emp Provide dept Attribute get Method .

<!-- Cascade assignments -->
<bean id="emp" class="com.atguigu.spring5.bean.Emp">
<!-- Set two common properties -->
<property name="ename" value="lucy"></property> <property name="gender" value=" Woman "></property>
<!-- Writing a -->
<property name="dept" ref="dept"></property>
<!-- Write two -->
<property name="dept.dname" value=" Technology Department "></property>
</bean>
<bean id="dept" class="com.atguigu.spring5.bean.Dept">
<property name="dname" value=" Finance Department "></property>
</bean>

6、 Inject set properties ( Array ,List,Map)

Let's say I have a Stu class

public class Stu {
private String[] courses;
private List<String> list;
private Map<String,String> map;
private Set<String> set;
public void setCourses(String[] courses) {
this.courses = courses;
}
public void setList(List<String> list) {
this.list = list;
}
public void setMap(Map<String, String> map) {
this.map = map;
}
public void setSet(Set<String> set) {
this.set = set;
}
}

stay xml Inject these collection attributes into the configuration file

<bean id="stu" class="com.oymn.spring5.Stu">
<!-- Array type property Injection -->
<property name="courses">
<array>
<value>java Course </value>
<value> Database course </value>
</array>
</property>
<!--List Type attribute Injection -->
<property name="list">
<list>
<value> Zhang San </value>
<value> Li Si </value>
</list>
</property>
<!--Map Type attribute Injection -->
<property name="map">
<map>
<entry key="JAVA" value="java"></entry>
<entry key="PHP" value="php"></entry>
</map>
</property>
<!--Set Type attribute Injection -->
<property name="set">
<set>
<value>Mysql</value>
<value>Redis</value>
</set>
</property>
</bean>

7、 The above set values are all strings , If it's an object , as follows :

How to write it : aggregate + external bean

<!-- Create multiple course object -->
<bean id="course1" class="com.atguigu.spring5.collectiontype.Course">
<property name="cname" value="Spring5 frame "></property>
</bean>
<bean id="course2" class="com.atguigu.spring5.collectiontype.Course">
<property name="cname" value="MyBatis frame "></property>
</bean>
<!-- Inject list Collection types , Value is the object -->
<property name="courseList">
<list>
<ref bean="course1"></ref>
<ref bean="course2"></ref>
</list>
</property>

8、 Extract the set injection part

Use util label , This is different bean You can use the same set injection part .

<!-- Extract the set injection part -->
<util:list id="booklist">
<value> Yijinjing </value>
<value> nine men's power </value>
</util:list>
<bean id="book" class="com.oymn.spring5.Book">
<property name="list" ref="booklist"></property>
</bean>

IOC operation Bean management (FactoryBean)

Spring There are two kinds of Bean

  • One is Ordinary Bean: Defined in the configuration file bean A type is a return type
@Data
public class Course {
private String cname;
}
<?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:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
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/context
http://www.springframework.org/schema/context/spring-context.xsd">
<bean id="myBean" class="factorybean.MyBean">
</bean>
</beans>
public class TestSpring5Demo {
@Test
public void test(){
ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
MyBean myBean = context.getBean("myBean", MyBean.class);
System.out.println(myBean);//[email protected]
}
}
  • The other is factory Bean(FactoryBean): Define... In the configuration file bean The type can be different from the return type .
    • First step : Create a class , Let this class be a factory bean, Implementation interface FactoryBean
    • The second step : Implement the methods in the interface , Define the returned... In the implemented method bean type
@Data
public class Course {
private String cname;
}
<?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:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
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/context
http://www.springframework.org/schema/context/spring-context.xsd">
<bean id="myBean" class="factorybean.MyBean">
</bean>
</beans>
public class MyBean implements FactoryBean<Course> {
// Define return bean, The defined paradigm is returned Course, instead of xml As defined in MyBean
@Override
public Course getObject() throws Exception {
Course course = new Course();
course.setCname("abc");
return course;
}
@Override
public Class<?> getObjectType() {
return null;
}
@Override
public boolean isSingleton() {
return false;
}
}
public class TestSpring5Demo {
@Test
public void test1(){
ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
Course course = context.getBean("myBean", Course.class);
System.out.println(course);//Course(cname=abc)
}
}

Bean Scope of action :

  • stay Spring in , By default bean Is a singleton object

image-20210719113035226

The execution result is the same :

image-20210719113122345

adopt bean Labeled scope attribute To set single instance or multiple instances .
Scope Property value :

  • **singleton:** The default value is , Represents a single instance object . When the configuration file is loaded, a single instance object is created .
  • prototype: Represents a multi instance object . The object is not created when the configuration file is loaded , Calling getBean Method to create a multi instance object .

image-20210719113500730

  The execution results are different :

image-20210719113518353

Bean Life cycle of :

Spring The complete life cycle starts from establish Spring The container starts , Until the end Spring Destruction of containers bean:

(1) Created by constructor bean example ( Execute parameterless construction )

(2) by bean Property settings and for other bean quote ( call set Method )

(3) hold bean Instance passing bean Post processor method postProcessBeforeInitialization

(4) call bean The initialization method of ( The configuration initialization method is needed )

(5) hold bean Instance passing bean Post processor method postProcessAfterInitialization

(6)bean It's ready to use ( The object gets )

(7) When the container is closed , call bean The way to destroy ( The method of configuration destruction is needed )

demonstration bean Life cycle of

public class Orders {
private String orderName;
public Orders() {
System.out.println(" First step : Execute the parameterless construction method to create bean example ");
}
public void setOrderName(String orderName) {
this.orderName = orderName;
System.out.println(" The second step : call set Method to set the property value ");
}
// Initialization method
public void initMethod(){
System.out.println(" Step four : Execute initialization method ");
}
// Destruction method
public void destroyMethod(){
System.out.println(" Step seven : Execution of destruction methods ");
}
}
// Implement the post processor , Need to achieve BeanPostProcessor Interface
public class MyBeanPost implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println(" The third step : take bean Instance passed to bean Post processor postProcessBeforeInitialization Method ");
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println(" Step five : take bean Instance passed to bean Post processor postProcessAfterInitialization Method ");
return bean;
}
}
<bean id="orders" class="com.oymn.spring5.Orders" init-method="initMethod" destroy-method="destroyMethod">
<property name="orderName" value="hahah"></property>
</bean>
<!-- To configure bean Post Processors , After this configuration, the whole xml Inside bean It's all this post processor -->
<bean id="myBeanPost" class="com.oymn.spring5.MyBeanPost"></bean>
@Test
public void testOrders(){
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
Orders orders = context.getBean("orders", Orders.class);
System.out.println(" Step six : obtain bean Instance object ");
System.out.println(orders);
// Let go by hand bean Example destruction
context.close();
}

Execution results :

image-20210720122628081

xml Automatic assembly ( Rarely used , It's usually annotated ):

According to the specified assembly rules ( Property name or property type ),Spring Automatically inject matching attribute values

  • Auto assemble according to attribute name : requirement emp The name of the property in the class dept and bean Labeled id value dept equally , To recognize :

<!-- Appoint autowire The property value is byName-->
<bean id="emp" class="com.oymn.spring5.Emp" autowire="byName"></bean>
<bean id="dept" class="com.oymn.spring5.Dept"></bean>
  • Automatically assemble according to the attribute type : Ask for the same xml There cannot be two files of the same type bean, Otherwise, you can't identify which one :

<!-- Appoint autowire The property value is byType-->
<bean id="emp" class="com.oymn.spring5.Emp" autowire="byType"></bean>
<bean id="dept" class="com.oymn.spring5.Dept"></bean>
  • Common assembly realizes :
<?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:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
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/context
http://www.springframework.org/schema/context/spring-context.xsd">
<bean id="emp" class="autowired.Emp">
<property name="dept" ref="dept"></property>
</bean>
<bean id="dept" class="autowired.Dept">
</beans>
public class Dept {
}
@ToString
@Data
public class Emp {
private Dept dept;
public void test(){
System.out.println(dept);
}
}
@Test
public void testEmp(){
ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");
Emp emp = context.getBean("emp", Emp.class);
System.out.println(emp);
}
  • Automatic assembly realizes :
<?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:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
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/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- Automatic assembly
bean Tag attributes autowired, Configure automatic assembly
autowired Property usually has two values :
byName: Inject according to the attribute name , Injection value bean Of id value and Class attribute names are the same
byType: Inject... According to the property type
-->
<bean id="emp" class="autowired.Emp" autowire="byName">
</bean>
<bean id="dept" class="autowired.Dept"></bean>
</beans>
public class Dept {
}
@ToString
@Data
public class Emp {
private Dept dept;
public void test(){
System.out.println(dept);
}
}
@Test
public void testEmp(){
ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");
Emp emp = context.getBean("emp", Emp.class);
System.out.println(emp);
}

Operate through the external properties file bean:

For example, configure database information :

  1. Import Druid connection pool jar package

  2. Create an external properties file ,properties Format file , Write database information

image-20210731004522456

      3. introduce context The name space , adopt context Label import external property file , Use “${}” Get the corresponding value in the file

image-20210731010320233







2.3. IOC operation Bean management ( Based on annotations )

  • Format :@ Annotated name ( Property name = Property value , Property name = Property value ,……)
  • Annotations can be applied to classes , attribute , Method .
  • The purpose of using annotations : simplify xml To configure

(1) Create objects based on annotations :

spring Provides four annotations for creating objects :

  • @Component
  • @Service: Commonly used in Service layer
  • @Controller: Commonly used in web layer
  • @ Repository: Commonly used in Dao layer

technological process :

1. Introduce dependencies :

2. Turn on component scanning : scanning base-package Package all annotated classes and create objects for them

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

3. com.oymn.spring5.Service There is one stuService class

// Through here @Component Annotation to create objects , In parentheses value The value of is the same as before xml Create objects using id, For later use through id To get the object
// The contents in brackets can also be omitted , The default is the class name and the initial is lowercase
// You can use the other three annotations
@Component(value="stuService")
public class StuService {
public void add(){
System.out.println("addService");
}
}

4.  So you can get through getBean Method to get stuService Object

ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean4.xml");
StuService stuService = context.getBean("stuService", StuService.class);
System.out.println(stuService);
stuService.add();

Open the detailed configuration of component scanning :

  1. use-default-fileters Set to false Indicates that the default filter is not used , adopt include-filter To set scan only com.oymn Everything under the bag @Controller Modified class .
<context:component-scan base-package="com.oymn" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

 2. exclude-filter Set which annotations are not scanned , In the example is @Controller Decorated classes are not scanned

<context:component-scan base-package="com.oymn">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

(2) Attribute injection based on annotation :

  • @Autowired Automatically assemble according to the attribute type

    establish StuDao Interface and StuDaoImpl Implementation class , by StuDaoImpl Add create object annotation

public interface StuDao {
public void add();
}
@Repository
public class StuDaoImpl implements StuDao {
@Override
public void add() {
System.out.println("StuDaoImpl");
}
}

StuService Class StuDao attribute , To add @Autowire annotation ,spring Automatically for stuDao Attributes to create StuDaoImpl object

@Component(value="stuService")
public class StuService {
@Autowired
public StuDao stuDao;
public void add(){
System.out.println("addService");
stuDao.add();
}
}
@Test
public void test1(){
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean4.xml");
StuService stuService = context.getBean("stuService", StuService.class);
System.out.println(stuService);
stuService.add();
}
  • test result :

    image-20210731164052536

  • @Qualifier Auto assemble according to attribute name

    When an interface has many implementation classes , Only pass @Autowire It is impossible to complete automatic assembly , So it needs to be reused @Qualifier Lock a class by name

    @Component(value="stuService")
    public class StuService {
    @Autowired
    @Qualifier(value="stuDaoImpl") // This allows you to explicitly specify stuDaoImpl This implementation class
    public StuDao stuDao;
    public void add(){
    System.out.println("addService");
    stuDao.add();
    }
    }
    

     @Resource You can inject... By type , You can also inject... By name

  • @Resources No spring Medium , yes java Expansion pack, import javax.annotation.Resource; in ,spring Not recommended .
@Component(value="stuService")
public class StuService {
//@Resource // Injection by type
@Resource(name="stuDaoImpl") // Inject by name
public StuDao stuDao;
public void add(){
System.out.println("addService");
stuDao.add();
}
}

@Value Injects common type properties

@Value(value = "abc")
private String name;

(3) Fully annotated development :

Create configuration class , replace xml The configuration file

@Configuration // Indicates that it is a configuration class
@ComponentScan(basePackages = "com.oymn") // Turn on component scanning
public class SpringConfig {
}

Test class :

@Test
public void test2(){
// establish AnnotationConfigApplicationContext object
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
StuService stuService = context.getBean("stuService", StuService.class);
System.out.println(stuService);
stuService.add();
}

3、AOP

3.1. Underlying principle

  • Section oriented programming : utilize AOP Parts of the business logic can be isolated , Thus the degree of coupling between the parts of the business logic is reduced , Improve program reusability , At the same time improved the efficiency of development .
  • Generally speaking, it's : Add new functionality without modifying the code .

  • AOP The bottom layer is realized by dynamic agent :
    • The first one is : With interface , Use JDK A dynamic proxy : Create a proxy object for the interface implementation class , Methods to enhance classes

  • The second kind : No interface , Use CGLIB A dynamic proxy : Create proxy objects for subclasses of the current class , Methods to enhance classes

JDK Dynamic proxy example :

adopt java.lang.reflect.Proxy class Of newProxyInstance Method Create a proxy class .

  • newProxyInstance Method :

image-20210801004308007

  • Parameter one : Class loader
  • Parameter two : The class of the enhanced method , This class implements the interface , Support multiple interfaces
  • Parameter 3 : Realization InvocationHandle Interface , rewrite invoke Method to add new functions

The code for :

public interface UserDao {
public int add(int a, int b);
public int multi(int a, int b);
}
public class UserDaoImpl implements UserDao {
@Override
public int add(int a, int b) {
System.out.println("add Method executed ...");
return a+b;
}
@Override
public int multi(int a, int b) {
System.out.println("add Method executed ...");
return a*b;
}
}
public class JDKProxy {
public static void main(String[] args) {
// The interface implemented by the class of the required proxy , Support multiple interfaces
Class[] interfaces = {UserDao.class};
// Class loader
UserDaoImpl userDao = new UserDaoImpl();
// call newProxyInstance Method to create a proxy class
UserDao dao = (UserDao)Proxy.newProxyInstance(JDKProxy.class.getClassLoader(),interfaces,new UserDaoProxy(userDao));
int res = dao.add(1,2);
System.out.println(res);
}
// Before method execution add Parameters passed [1, 2]
//add Method executed ...
// Method after execution [email protected]
//3
}
// Create proxy object
class UserDaoProxy implements InvocationHandler{
//1 Whose proxy object is created , Pass who
// There are parameter constructors
private Object obj;
// Pass the class of the required proxy through the parameterized constructor
public UserDaoProxy(Object obj){
this.obj = obj;
}
// Enhanced logic
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// Before method execution
System.out.println(" Before method execution "+method.getName()+" Parameters passed "+ Arrays.toString(args));
// Enhanced method execution ,// Execute the original code
Object res = method.invoke(obj, args);
// After method
System.out.println(" Method after execution "+obj);
return res;
}
}

Running results :

 Before method execution add Parameters passed [1, 2]
add Method executed ...
Method after execution [email protected]
3

3.2. be based on AspectJ Realization AOP operation

(1)AOP Related terms :

  • Connection point : Class Methods that can be enhanced , Called connection point .
  • The breakthrough point : Actually enhanced methods , It's called the pointcut . for example : The logic of login .
  • notice ( enhance ): The enhanced part of the logic code . for example : Add permission judgment . There are many types of notifications :
    • Pre notice : The enhanced part of the code is in front of the original code .
    • The rear notice : The enhanced part of the code is behind the original code .
    • Surrounding the notification : The enhanced part of the code is in front of the original code , Also behind the original code .
    • Abnormal notice : The original code will be executed only after an exception occurs .
    • Final notice : Similar to finally Which part
  • section : finger The action of applying notifications to pointcuts . for example : Add permission judgment to login logic .

Spring Frameworks are generally based on AspectJ Realization AOP operation .

What is? AspectJ:

AspectJ No Spring Part of the , Independent AOP frame , Generally put AspectJ and Spring Use frame together , Conduct AOP operation .

(2) be based on AspectJ Realization AOP There are two ways :

  • be based on xml Configuration file implementation
  • Implement based on annotation ( Use )

(3) Pointcut expression

Pointcut expressions work : Know which method in which class to enhance .

  • grammar :execution([ Permission modifier ] [ Return type ] [ Class full path ] [ Method name ] [ parameter list ])
  • give an example 1: Yes com.crane.dao.BookDao The inside of the class add enhanced , Class full path : com.crane.dao.BookDao

execution(* com.crane.dao.BookDao.add(..))

execution(public Omit  com.crane.dao.BookDao.add(..))

  • give an example 2: Yes com.crane.dao.BookDao All the methods in the class are enhanced

execution(* com.crane.dao.BookDao.*(..))

  • give an example 3: Yes com.crane.dao All the classes in the package , All methods in the class are enhanced

execution(* com.crane.dao.*.* (..))

(1) Based on annotation

  • 1、 Create a class , Define methods in classes
  • 2、 Create enhancement classes , Write enhanced logic
  • 3、 Configure notification
    • stay spring In profile , Turn on annotation scanning
    • Use annotations to create User and UserProxy object
    • Add... To the enhanced class @Aspect
    • stay spring Enable the generation agent object in the configuration file
  • 4、 Configure different types of notifications
    • In the enhanced class , Add a notification type annotation to the notification method , Use pointcut expressions to configure

add to AOP rely on

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<version>2.6.1</version>
</dependency>
// Enhanced classes
@Component
public class User {
public void add(){
System.out.println("User.add()");
}
}
@Component
@Aspect // Use Aspect annotation
public class UserProxy {
// Pre notice
@Before(value="execution(* com.oymn.spring5.User.add(..))")
public void before(){
System.out.println("UserProxy.before()");
}
// The rear notice
@AfterReturning(value="execution(* com.oymn.spring5.User.add(..))")
public void afterReturning(){
System.out.println("UserProxy.afterReturning()");
}
// Final notice
@After(value="execution(* com.oymn.spring5.User.add(..))")
public void After(){
System.out.println("UserProxy.After()");
}
// Abnormal notice
@AfterThrowing(value="execution(* com.oymn.spring5.User.add(..))")
public void AfterThrowing(){
System.out.println("UserProxy.AfterThrowing()");
}
// Surrounding the notification
@Around(value="execution(* com.oymn.spring5.User.add(..))")
public void Around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
System.out.println(" Before surround ");
// call proceed Method executes the original part of the code
proceedingJoinPoint.proceed();
System.out.println(" After surround ");
}
}

To configure xml 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.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">
<!-- Turn on component scanning -->
<context:component-scan base-package="aopanno"></context:component-scan>
<!-- Turn on AspectJ Generate proxy objects -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>

Test class :

@Test
public void test2(){
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
User user = context.getBean("user", User.class);
user.add();
}

Running results :

image-20210801210024676

  There is no exception notification in the running result , stay add Method to add int i = 1/0;

public void add(){
int i = 1/0;
System.out.println("User.add()");
}

Running results : You can also see from here , But when something goes wrong ,After The final notice has been executed , and AfterReturning The post notification did not execute .

image-20210801210304774


For the example above , There are many notification entry points that are the same approach , therefore , This pointcut can be extracted : adopt @Pointcut annotation

@Pointcut(value="execution(* com.oymn.spring5.User.add(..))")
public void pointDemo(){
}
// Pre notice
@Before(value="pointDemo()")
public void before(){
System.out.println("UserProxy.before()");
}

Set enhancement class priority :

When multiple enhancement classes enhance the same method , Can pass **@Order( Numerical value ) To set the priority of the enhancement class , The smaller the number, the higher the priority .**

@Component
@Aspect
@Order(1)
public class PersonProxy{
}

Fully annotated development  :

You can completely get rid of... By configuring classes xml The configuration file :

@Configuration
@ComponentScan(basePackages = "com.oymn.spring5")
//@EnableAspectJAutoProxy The annotation is equivalent to the above xml Configured in the file <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class Config {
}

(2) be based on xml The way

This method is rarely used in development , Understanding can .

establish Book and BookProxy class

public class Book {
public void buy(){
System.out.println("buy()");
}
}
public class BookProxy {
public void before(){
System.out.println("before()");
}
}

To configure xml file :

<!-- Create objects -->
<bean id="book" class="com.oymn.spring5.Book"></bean>
<bean id="bookProxy" class="com.oymn.spring5.BookProxy"></bean>
<aop:config>
<!-- The breakthrough point -->
<aop:pointcut id="p" expression="execution(* com.oymn.spring5.Book.buy(..))"/>
<!-- Configuration aspect -->
<aop:aspect ref="bookProxy">
<aop:before method="before" pointcut-ref="p"/> <!-- take bookProxy Medium before Method is configured as the pre notification of the pointcut -->
</aop:aspect>
</aop:config>

aop:

stay SpringBoot of use SpringAOP Realize the logging function - Wang god - Blog Garden

SpringBoot Use in AOP_AlanLee97 The blog of -CSDN Blog _springboot Use aop

SpringBoot Use AOP_ Lao Yang's blog -CSDN Blog _springboot Use aop

copyright:author[CodingALife],Please bring the original link to reprint, thank you. https://en.javamana.com/2022/01/202201261610215925.html