catalogue
1.4 Bean Management: Implementation Based on xml configuration file
1.8 automatic assembly (xml mode)
1.9 introducing external configuration files into bean s
1.10 Bean Management: Annotation Based Implementation
1.10.1 creating objects based on annotations
1.10.2 attribute injection based on annotation
1.10.3 fully annotated development and Implementation
2.3 JDK dynamic Proxy implementation (Proxy)
2.3.2 formal implementation code
2.4 common AOP operating terms
2.5 implementing AOP in Spring
2.5.2 implementation of AOP based on AspectJ annotation
2.5.3 full use of annotation development
2.5.5 implementation of AOP based on xml configuration file
1 IOC
1.1 concept
(1) IOC: inversion of control, leaving the process of object creation and calling between objects to Spring for management.
(2) Purpose of using IOC: reduce coupling
Why IOC can reduce coupling, refer to: Why can IOC in Spring reduce coupling?
1.2 bottom layer principle
The underlying principles include: xml parsing (configuration file reading), factory mode and reflection
- Configure the path (or annotation Implementation) of the class in xml
- The corresponding classes are obtained through xml parsing and reflection
- This class is called through factory mode
IOC features: the calling class does not need to modify the code because the path of the called class changes. The called class path is written in the xml file. If the path changes later, it only needs to be modified into a new path in the xml file, and the codes in other places do not need to be modified.
1.3 IOC container
The IOC idea is based on the IOC container, and the bottom layer of the IOC container is the object factory.
Spring provides two ways to implement IOC container, that is, there are two interface implementations:
- BeanFactory: the basic implementation of IOC container. It is an interface used internally by Spring and is not provided to developers.
Features: the object will not be created when loading the configuration file, but will be created when obtaining the object (use).
- ApplicationContext: the sub interface of BeanFactory interface, which provides more and more powerful functions and is generally used by developers.
Features: when loading the configuration file, the objects in the configuration file will be created.
@Test public void testAdd(){ //(1) Load spring configuration file // ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml"); // Method 1 BeanFactory context = new ClassPathXmlApplicationContext("bean1.xml"); // Method 2 //(2) Gets the object created by the configuration User user = context.getBean("user",User.class); System.out.println(user); user.add(); }
Implementation class of ApplicationContext
1.4 Bean Management: Implementation Based on xml configuration file
Bean management refers to two operations:
- Spring creates objects;
- Spring injection properties.
There are two ways to manage beans:
- Implementation based on xml configuration file;
- Based on annotation.
Creating objects based on xml
<bean id="user" class="com.yxb.spring5.User"></bean>
(1) By using bean tags in xml configuration files, you can create objects.
(2) There are many properties in the bean tag, including common properties:
- - id: unique identification
- - Class: class full path (package class path)
(3) When creating an object, the parameterless constructor is executed by default to complete the creation of the object.
Attribute injection based on xml
DI: dependency injection (i.e. injection attribute)
Spring supports two injection methods:
(1) Using the set method
Examples are as follows:
// Attribute injection using set method public class Book { private String bookName; public void setBookName(String bookName) { this.bookName = bookName; } public void testDemo() { System.out.println("bookName=" + bookName); } }
<!-- use set Method--> <bean id="book" class="com.yxb.spring5.Book"> <!--use property Complete attribute injection name: Attribute name in class value: Values injected into attributes --> <property name="bookName" value="java Programming thought"></property> </bean>
Test code:
@Test public void testBook(){ // 1 load spring configuration file ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml"); // 2 get the object created by configuration Book book = context.getBean("book",Book.class); System.out.println(book); book.testDemo(); }
Test results:
com.yxb.spring5.Book@4fb64261
bookName=java programming idea
(2) Use a parameterized constructor
Examples are as follows:
// Property injection using a parameterized constructor public class Book { private String bookName; public Book(String bookName) { this.bookName = bookName; } public void testDemo() { System.out.println("bookName=" + bookName); } }
<!--Property injection using a parameterized constructor--> <bean id="book" class="com.yxb.spring5.Book"> <constructor-arg name="bookName" value="spring Getting started to giving up"></constructor-arg> </bean>
Test code run results:
com.yxb.spring5.Book@2eda0940
bookName=spring getting started to giving up
Using p namespace injection can simplify the writing of xml.
1.5 two types of beans
Spring has two types of bean s:
1. Ordinary bean: the bean type defined in the configuration file is the return type;
2. Factory bean: the bean type defined in the configuration file can be different from the return type.
The specific implementation of FactoryBean is as follows:
(1) The first step is to create a class that acts as a factory bean and implements the interface FactoryBean;
(2) The second step is to implement the methods in the interface and define the returned bean type in the implemented methods.
The specific example code is as follows:
public class MyBean implements FactoryBean<Course> { //Define return bean @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; } }
<bean id="myBean" class="com.atguigu.spring5.factorybean.MyBean"> </bean>
Test code:
@Test public void test3() { ApplicationContext context = new ClassPathXmlApplicationContext("bean3.xml"); Course course = context.getBean("myBean", Course.class); System.out.println(course); }
1.6 scope of bean
(1) In Spring, you can set whether the bean instance is single instance or multi instance.
(2) In Spring, bean s are singleton objects by default.
Single instance: the object obtained multiple times is the same.
Code example:
@Test public void testBook(){ // 1 load spring configuration file ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml"); // 2 get the object created by configuration Book book1 = context.getBean("book",Book.class); Book book2 = context.getBean("book",Book.class); System.out.println(book1); System.out.println(book2); }
Operation results:
com.yxb.spring5.Book@2eda0940
com.yxb.spring5.Book@2eda0940
It can be seen from the results that the addresses of the two objects are the same.
The scope property allows you to set whether an object is single instance or multi instance.
<bean id="book" class="com.yxb.spring5.Book" scope="prototype"> <constructor-arg name="bookName" value="spring Getting started to giving up"></constructor-arg> </bean>
Properties of scope:
- --singleton: single instance (the default value). A single instance object will be created when the configuration file is loaded.
- --prototype: multiple instances. Objects are created only when the getBean() method is called.
1.7 Bean life cycle
Process from object creation to object destruction:
- Create Bean instance through constructor (no parameter construction);
- Set the value for the Bean attribute and reference to other beans (call the set method);
- Call the Bean initialization method (configuration required);
- Bean can be used (the object is obtained);
- When the container is closed, call the Bean destruction method (which needs to be configured).
Code example (xml mode):
public class Book { private String bookName; public Book() { System.out.println("The first step is to create a parameterless constructor bean example"); } public void setBookName(String bookName) { this.bookName = bookName; System.out.println("Step 2, call set Method to set the property value"); } // Method of bean initialization public void initMethod(){ System.out.println("Step 3: execute the initialization method"); } // Method of bean destruction public void destoryMethod(){ System.out.println("Step 5: execute the destruction method"); } public void testDemo() { System.out.println("bookName=" + bookName); } }
<bean id="book" class="com.yxb.spring5.Book" init-method="initMethod" destroy-method="destoryMethod"> <property name="bookName" value="java Programming thought"></property> </bean>
@Test public void testBook(){ // 1 load spring configuration file ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml"); // 2 get the object created by configuration Book book = context.getBean("book",Book.class); System.out.println("Step 4: get the created bean Instance object"); System.out.println(book); book.testDemo(); // Call the method of bean destruction ((ClassPathXmlApplicationContext) context).close(); }
In fact, in addition to the above five steps, there are two steps in the Bean's life cycle (before and after initialization), which is called post processor. The complete seven steps are as follows:
- Create Bean instance through constructor (no parameter construction);
- Set the value for the Bean attribute and reference to other beans (call the set method);
- A method of passing the Bean instance to the Bean post processor;
- Call the Bean initialization method (configuration required);
- Another method of passing the Bean instance to the Bean post processor;
- Bean can be used (the object is obtained);
- When the container is closed, call the Bean destruction method (which needs to be configured).
How to create a post processor:
- Create a class, implement the interface BeanPostProcessor, and create a post processor (there are two methods Before and After, which are executed Before and After initialization respectively);
- Configure in the xml file.
1.8 automatic assembly (xml mode)
What is automatic assembly?
The previous method of setting the name and value of the property in the property tag in xml is manual assembly (as shown in the following code).
<property name="bookName" value="java Programming thought"></property>
Automatic assembly is to inject the matching attribute values automatically according to the specified assembly rules (attribute name or attribute type).
Manual assembly code example:
(1) Create two object classes
public class Dept { } public class Emp { private Dept dept; public void setDept(Dept dept) { this.dept = dept; } @Override public String toString() { return "Emp{" + "dept=" + dept + '}'; } }
(2) Code for xml file (manual assembly):
<bean id="emp" class="com.yxb.spring5.autowire.Emp"> <property name="dept" ref="dept"></property> </bean> <bean id="dept" class="com.yxb.spring5.autowire.Dept"></bean>
(3) Test code
@Test public void test3(){ // 1 load spring configuration file ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml"); // 2 get the object created by configuration Emp emp = context.getBean("emp",Emp.class); System.out.println(emp); }
Test code run results:
Emp{dept=com.yxb.spring5.autowire.Dept@2de8284b}
Using autowire in the bean tag can realize automatic assembly. The code is as follows:
<!-- automatic assembly use bean Label properties autowire,Configure auto assembly autowire Property has two common values: byName: Inject value according to attribute name bean of id The value is the same as the class attribute name byType: Injection according to attribute type --> <bean id="emp" class="com.yxb.spring5.autowire.Emp" autowire="byName"></bean> <bean id="dept" class="com.yxb.spring5.autowire.Dept"></bean>
Automatic assembly is divided into the following types:
- no: set Bean dependencies manually without automatic assembly.
- byName: automatically assemble according to Bean's name.
- byType: automatically assemble according to the type of Bean.
- Constructor: similar to byType, but it is a parameter applied to the constructor. If there is exactly one Bean with the same parameter type as the constructor, it can be assembled automatically, otherwise an error will be caused.
- autodetect: if there is a default constructor, it will be assembled automatically by constructor; otherwise, it will be assembled automatically by byType.
be careful:
- According to the type, if there are beans of the same type, there will be a situation that you don't know which bean to use.
- xml based implementations are rarely used, and are generally implemented based on annotations.
1.9 introducing external configuration files into bean s
Only the general steps are described here, as follows:
- Create the properties configuration file;
- Introduce the context namespace on the bean file (xml file);
- Use ${[parameter name]} The corresponding parameter configuration is introduced.
1.10 Bean Management: Annotation Based Implementation
What is annotation?
(1) Annotations are special tags for code.
(2) Annotations can be loaded on classes, methods, and properties.
(3) The purpose of using annotations is to simplify the configuration of xml.
1.10.1 creating objects based on annotations
Spring provides the following four annotations for creating objects in Bean Management:
- @Component
- @Service
- @Controller
- @Repository
The functions of the above four annotations are the same and can be used to create Bean instances.
You can use corresponding annotations in different places to distinguish them, but there will be no error if they are mixed.
To create an object based on annotations:
(1) Introducing aop dependencies
(2) Enable component scanning (indicate which file directory to scan)
<?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 http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- Enable component scanning. If multiple packages are scanned, they are separated by commas --> <context:component-scan base-package="com.yxb.spring5.annotation"></context:component-scan> </beans>
(3) Create a class and add comments on it
// The value in the annotation may not be written. If it is not written, it is the class name by default, and the initial letter is lowercase // All four annotations can be used, and the results are the same @Component(value = "userService") public class UserService { public void add(){ System.out.println("user-add"); } }
The tests are as follows:
@Test public void test4(){ // 1 load spring configuration file ApplicationContext context = new ClassPathXmlApplicationContext("annotation_bean.xml"); // 2 get the object created by configuration UserService userService = context.getBean("userService",UserService.class); System.out.println(userService); userService.add(); }
The output is as follows:
com.yxb.spring5.annotation.UserService@7a52f2a2
user-add
1.10.1.1 component scanning details configuration
Example 1: set what to scan
<!--Example 1 use-default-filters="false" Indicates that the default is not used now filter,Self configuration filter context:include-filter ,Set what to scan --> <context:component-scan base-package="com.atguigu" use-defaultfilters="false"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan>
Example 2: set what not to scan
<!--Example 2 Next, configure all contents of the scanning package context:exclude-filter: Set what is not scanned --> <context:component-scan base-package="com.atguigu"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan>
1.10.2 attribute injection based on annotation
There are four annotations for attribute injection in Spring:
- @Autowired: inject according to attribute type
- @Qualifier: inject according to the attribute name and use it with @ Autowired
- @Resource: it can be injected according to type or name (this annotation is in the javax extension package, and Spring officially recommends the above two)
- @Value: inject common type attributes (the above three are for object types)
Suppose you need to inject dao objects into the service layer. The steps of attribute injection are as follows:
- Create objects in the service and dao layers and add object annotations;
- Inject dao objects in the service layer, add dao type attributes in the service class, and add attribute injection annotations on the attributes.
1.10.3 fully annotated development and Implementation
(1) Create a configuration class to replace the xml configuration file
@Configuration // As a configuration class, replace the xml configuration file @ComponentScan(basePackages = {"com.yxb.spring5"}) public class SpringConfig { }
(2) Write test class code
@Test public void test5(){ // Load configuration class ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class); UserService userService = context.getBean("userService",UserService.class); System.out.println(userService); userService.add(); }
2 AOP
2.1 concept
(1) For aspect oriented 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.
(2) Popular Description: add new functions to the main functions without modifying the source code.
2.2 bottom layer principle
Dynamic agents are used at the bottom of AOP. There are two cases of dynamic agents:
(1) In the first case, JDK dynamic proxy is used
Create interfaces to implement class proxy objects and enhance class methods.
(2) In the second case, CGLIB dynamic proxy is used
Create proxy objects of subclasses and enhance the methods of classes.
2.3 JDK dynamic Proxy implementation (Proxy)
2.3.1 background knowledge
JDK dynamic Proxy uses Proxy Class to create a Proxy object.
Call newProxyInstance method
Method has three parameters:
- First parameter, class loader
- The second parameter is the class where the enhancement method is located. The interface implemented by this class supports multiple interfaces
- The third parameter is to implement this interface InvocationHandler, create a proxy object, and enhance the part
2.3.2 formal implementation code
(1) Create interfaces and define methods
public interface ItemDao { public int add(int a,int b); public String update(String id); }
(2) Create interface implementation classes and implement methods
public class ItemDaoImpl implements ItemDao { @Override public int add(int a, int b) { System.out.println("add Method is executed...."); return a+b; } @Override public String update(String id) { return id; } }
(3) Creating interface Proxy objects using Proxy classes
public class JDKProxy { public static void main(String[] args) { // Create interface implementation class proxy object Class[] interfaces = {ItemDao.class}; ItemDaoImpl itemDao = new ItemDaoImpl(); // Writing of anonymous inner class // Proxy.newProxyInstance(JDKProxy.class.getClassLoader(), interfaces, new InvocationHandler() { // @Override // public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // return null; // } // }); // Writing of non anonymous inner classes ItemDao dao = (ItemDao) Proxy.newProxyInstance(JDKProxy.class.getClassLoader(), interfaces, new ItemDaoProxy(itemDao)); int res = dao.add(1,2); System.out.println(res); } } // Create proxy object code class ItemDaoProxy implements InvocationHandler { //Pass the created proxy object and the created proxy object through the parameterized structure private Object obj; public ItemDaoProxy(Object obj) { this.obj = obj; } // Enhanced logic @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // Before method System.out.println("Method...."+method.getName()+" :Parameters passed..."+ Arrays.toString(args)); // Enhanced method execution Object res = method.invoke(obj, args); // After method System.out.println("Method...."+obj); return res; } }
2.4 common AOP operating terms
2.4.1 connection points
In a class, which methods can be enhanced in theory are called join points.
2.4.2 entry point
The method that is actually really enhanced is called the pointcut.
2.4.3 notification (enhanced)
The logical part of the actual enhancement is called notification (enhancement).
There are five types of notifications:
- Advance notice @ Before
- Post notification @ AfterReturning (return notification, notify after return value) [it will not be executed in case of exception]
- Surround notification @ Around (both before and after the enhanced method)
- Exception notification @ AfterThrowing
- Final notice @ After [execute with or without exception]
2.4.4 section
Aspect is an action, and the process of applying notifications to pointcuts is called aspect.
2.5 implementing AOP in Spring
2.5.1 background knowledge
1. Spring framework is generally based on AspectJ Implement AOP operation.
AspectJ is not a part of Spring. It is an independent AOP framework. Generally, AspectJ and Spirng framework are used together for AOP operation.
2. There are two ways to implement AOP operation based on AspectJ:
(1) Implementation of configuration file based on xml
(2) Annotation based implementation (more convenient)
3. Introduce AOP related dependencies into the project.
4. Pointcut expression
(1) Pointcut expression function: know which method in which class to enhance.
(2) Syntax structure: execution([permission modifier] [return type] [class full path] [method name] ([parameter list]))
Example 1: enhance add in the com.atguigu.dao.BookDao class
execution(* com.atguigu.dao.BookDao.add(..))
Example 2: enhance all methods in the com.atguigu.dao.BookDao class
execution(* com.atguigu.dao.BookDao.* (..))
Example 3: enhance all classes and methods in the com.atguigu.dao package
execution(* com.atguigu.dao.*.* (..))
(* indicates wildcard)
2.5.2 implementation of AOP based on AspectJ annotation
1. Create a class and define methods in the class
// Enhanced class public class Item { public void add(){ System.out.println("item---add........."); } }
2. Create enhancement classes (write enhancement logic)
In the enhanced class, create methods so that different methods represent different notification types
// Enhanced class public class ItemProxy { // Before advice public void before(){ System.out.println("before......"); } }
3. Configure notifications
(1) In the spring configuration file, turn on annotation scanning
(2) Create Item and ItemProxy objects using annotations
(3) Add the annotation @ Aspect on the enhanced class
(4) Turn on the build proxy object in the spring configuration file
After the above steps, the code is as follows:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd"> <!--Enable annotation scanning--> <context:component-scan base-package="com.yxb.aopanno"></context:component-scan> <!-- open Aspect Generate proxy object--> <aop:aspectj-autoproxy></aop:aspectj-autoproxy> </beans>
// Enhanced class @Component public class Item { public void add(){ System.out.println("item---add........."); } }
// Enhanced class @Component @Aspect public class ItemProxy { // Before advice public void before(){ System.out.println("before......"); } }
4. Configure different types of notifications
In the enhanced class, add a notification type annotation on the notification method and configure it with a pointcut expression.
// Enhanced class @Component @Aspect public class ItemProxy { // Before advice // @The Before annotation indicates as a pre notification @Before(value = "execution(* com.yxb.aopanno.Item.add(..))") public void before(){ System.out.println("before......"); } //Post notification (notification returned, notification after return value) [it will not be executed in case of exception] @AfterReturning(value = "execution(* com.yxb.aopanno.Item.add(..))") public void afterReturning() { System.out.println("afterReturning........."); } //Final notice [execute with or without exception] @After(value = "execution(* com.yxb.aopanno.Item.add(..))") public void after() { System.out.println("after........."); } //Exception notification @AfterThrowing(value = "execution(* com.yxb.aopanno.Item.add(..))") public void afterThrowing() { System.out.println("afterThrowing........."); } //Around Advice @Around(value = "execution(* com.yxb.aopanno.Item.add(..))") public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { System.out.println("Before surround........."); //Enhanced method execution proceedingJoinPoint.proceed(); System.out.println("After surround........."); } }
Test code:
@Test public void testAopAnno(){ ApplicationContext context = new ClassPathXmlApplicationContext("aopanno_bean.xml"); Item item = context.getBean("item",Item.class); item.add(); }
Output results:
Before circling
before......
item---add.........
After circling
after.........
afterReturning.........
2.5.3 full use of annotation development
To create a configuration class, you do not need to create an xml configuration file
@Configuration // Enable annotation scanning @ComponentScan(basePackages = {"com.yxb"}) // Turn on Aspect to generate proxy objects @EnableAspectJAutoProxy(proxyTargetClass = true) public class ConfigAop { }
2.5.4 two details
2.5.4.1 same entry point extraction
Use the @ Pointcut annotation to extract the same Pointcut. The code example is as follows:
//Same pointcut extraction @Pointcut(value = "execution(* com.yxb.aopanno.Item.add(..))") public void pointdemo() { } // @The Before annotation indicates as a pre notification // Value value uses pointdemo() @Before(value = "pointdemo()") public void before(){ System.out.println("before......"); }
2.5.4.2 set priority of enhancement class
Multiple enhancement classes can be enhanced by the same method, and the priority of enhancement classes can be set.
Add the annotation @ order (numeric type value) on the enhanced class. The smaller the numeric type value, the higher the priority.
@Component @Aspect @Order(1) public class ItemProxy2
2.5.5 implementation of AOP based on xml configuration file
The implementation based on xml configuration file is cumbersome and less used. The steps are as follows:
1. Create two classes, enhanced class and enhanced class, and create methods
2. Create two class objects in the spring configuration file
<!--create object--> <bean id="book" class="com.yxb.aopxml.Book"></bean> <bean id="bookProxy" class="com.yxb.aopxml.BookProxy"></bean>
3. Configuring pointcuts in the spring configuration file
<!--to configure aop enhance--> <aop:config> <!--breakthrough point--> <aop:pointcut id="p" expression="execution(* com.yxb.aopxml.Book.buy(..))"/> <!--Configure section--> <aop:aspect ref="bookProxy"> <!--The enhancement effect is on the specific method--> <aop:before method="before" pointcut-ref="p"/> </aop:aspect> </aop:config>
3. Appendix
3.1 all codes and word notes
All codes and notes of personal actual operation:
3.2 references
The full text is mainly referred to: https://www.bilibili.com/video/BV1Vf4y127N5