Overview of Spring

1.1 summary of the Spring

Spring is an open source framework

2. Spring was born to simplify enterprise development. Using Spring, Javabeans can implement many functions that previously depended on EJBs. The same functionality that requires tedious configuration and complex code in EJB is very elegant and concise in Spring.

Spring is an IOC(DI) and AOP container framework.

4. Good features of Spring

1) Non-intrusive: Objects in spring-based applications can be independent of Spring’s API

2) Dependency Injection: DI — the most classic implementation of Dependency Injection (IOC).

3) Aspect Oriented Programming — AOP

4) Container: Spring is a container because it contains and manages the life cycle of application objects

5) Componentization: Spring makes it possible to compose a complex application using simple component configurations. You can combine these objects in Spring using XML and Java annotations.

6) One-stop: On the basis of IOC and AOP, it can integrate various open source frameworks for enterprise applications and excellent third party class libraries (in fact, Spring itself also provides SpringMVC for presentation layer and Spring JDBC for persistence layer).

5. Spring module

1.2 Setting up the Spring runtime Environment

1. Add the JAR package

1) Spring JAR package: Spring-framework-4.0.0. RELEASE\libs directory

Spring beans – 4.0.0. RELEASE. The jar

Spring – the context – 4.0.0. RELEASE. The jar

Spring – the core – 4.0.0. RELEASE. The jar

Spring – expression – 4.0.0. RELEASE. The jar

2) the Commons logging – 1.1.1. The jar

2. Create Spring configuration files as needed

IOC container and Bean configuration

2.1 the IOC and DI

2.1.1 the IOC (Inversion of Control) :Inversion of control

When the components in the application need to obtain resources, the traditional way is that the components take the initiative to obtain the required resources from the container. In this mode, developers often need to know how to obtain the specific resources in the specific container, which increases the learning cost and reduces the development efficiency.

Inversion of control completely subvert the traditional way of the application components for resources: reverses the resources acquisition direction – instead container active will be pushed to resources needed components, developers do not need to know how to create a container is resource objects, you just need to provide a way to receive resources, greatly reduce the learning cost, improve the efficiency of development. This behavior is also known as the passive form of lookup.

2.1.2 DI (Dependency Injection) :Dependency injection

Another way of expressing IOC is that a component receives an injection of resources from a container in some predefined way (for example, setter methods). This is more straightforward than the IOC.

2.1.3 IOC container implementation in Spring

1. The IOC container itself needs to be instantiated before an instance of the Bean can be read from the IOC container.

Spring provides two implementations of the IOC container

1) BeanFactory: The basic implementation of the IOC container, which is the internal infrastructure of Spring and is geared towards Spring itself, not provided to developers.

ApplicationContext: a subinterface to the BeanFactory that provides more advanced features. For Spring consumers, the ApplicationContext is almost always used instead of the underlying BeanFactory.

2.1.4 Main implementation classes of ApplicationContext

1, the ClassPathXmlApplicationContext: corresponding classpath configuration file of XML format

2, FileSystemXmlApplicationContext: configuration file corresponding to the XML file system format

3. Create a singleton bean at initialization, or you can configure the bean to be multi-instance.

2.1.5 ConfigurableApplicationContext

Is a subinterface of ApplicationContext that contains extension methods

Refresh () and close() give ApplicationContext the ability to start, close, and refresh the context.

2.1.6 WebApplicationContext

Designed specifically for WEB applications, it allows initialization to be done from a path relative to the WEB root directory

2.2 Getting beans by type

When you get a bean from an IOC container, you can also get it by its type in addition to its ID value. But if more than one bean of the same type is configured in the XML file, an exception will be thrown when it is fetched, so beans of the same type must be unique in the container.

HelloWorld helloWorld = cxt.getBean(HelloWorld. class);
Copy the code

2.3 Assigning values to bean properties

2.3.1 Path of assignment

1. Assign via the bean’s setXxx() method

2. Assign through the bean’s constructor

<bean id="book" class="com.atguigu.spring.bean.Book" >
    <constructor-arg value"10010"/>
    <constructor-arg value"Book01"/>
    <constructor-arg value"Author01"/>
    <constructor-arg value"20.2"/>
</bean>
Copy the code

1) Specify parameter positions by index values

<bean id="book" class="com.atguigu.spring.bean.Book" >
    <constructor-arg value"10010" index ="0"/>
    <constructor-arg value"Book01" index ="1"/>
    <constructor-arg value"Author01" index ="2"/>
    <constructor-arg value"20.2" index ="3"/>
</bean>
Copy the code

2) Distinguish overloaded constructors by type

<bean id="book" class="com.atguigu.spring.bean.Book" >
    <constructor-arg value"10010" index ="0" type="java.lang.Integer" />
    <constructor-arg value"Book01" index ="1" type="java.lang.String" />
    <constructor-arg value"Author01" index ="2" type="java.lang.String" />
    <constructor-arg value"20.2" index ="3" type="java.lang.Double" />
</bean >
Copy the code

Assign the cascading properties of the bean

<bean id="action" class="com.atguigu.spring.ref.Action">
    <property name="service" ref="service"/>
    <! Set cascading properties -->
    <property name="service.dao.dataSource" value="DBCP"/>
</bean>
Copy the code

4. The p namespace

To simplify the configuration of XML files, more and more XML files use attributes rather than child element configuration information. Spring introduced a new P namespace starting with version 2.5 that allows you to configure Bean properties as element properties. Using the P namespace simplifies the XML-based configuration even further.

<bean 
	id="studentSuper" 
	class="com.atguigu.helloworld.bean.Student"
	p:studentId="2002" p:stuName="Jerry2016" p:age="18" />
Copy the code

2.3.2 Available values

1. Literals

1) A value that can be represented as a string can be specified as a value attribute or as a value child node

2) Basic data types and their enclosing classes, String, and other types can take the way of literal injection

3) If the literal contains special characters, you can wrap the literal

2, a null value

<bean class="com.atguigu.spring.bean.Book" id="bookNull" >
    <property name"bookId" value ="2000"/>
    <property name"bookName">
        <null/>
    </property>
    <property name"author" value ="nullAuthor"/>
    <property name"price" value ="50"/>
</bean >
Copy the code

External declared beans

<bean id="shop" class="com.atguigu.spring.bean.Shop" >
    <property name"book" ref ="book"/>
</bean >
Copy the code

4. Internal beans

When a bean instance is used only for a particular property, it can be declared as an internal bean. The inner bean declaration is contained directly in the or element without setting any ID or name attributes. The inner bean cannot be used anywhere else

<bean id="shop2" class="com.atguigu.spring.bean.Shop" >
    <property name"book">
        <bean class"com.atguigu.spring.bean.Book" >
           <property name"bookId" value ="1000"/>
           <property name"bookName" value="innerBook" />
           <property name"author" value="innerAuthor" />
           <property name"price" value ="50"/>
        </bean>
    </property>
</bean >
Copy the code

2.3.3 Collection Properties

In Spring, you can configure collection properties with a set of built-in XML tags, such as:, or.

1. Arrays and Lists

To configure an attribute of type java.util.List, specify a tag that contains elements. These tags can be specified by specifying simple constant values, and by specifying references to other beans. By specifying the built-in bean definition. By specifying empty elements. You can even embed other collections.

Arrays, like lists, are defined using elements and can be used.

To configure java.util.Set, you need to use tags that define the same methods as List.

<bean id="shop" class="com.atguigu.spring.bean.Shop" >
    <property name"categoryList">
        <! -- List of literals -->
        <list>
            <value>The historical value > < /<value>Military value > < /</list>
    </property>
    <property name"bookList">
        <! List of bean references -->
        <list>
            <ref bean"book01"/>
            <ref bean"book02"/>
        </list>
    </property>
</bean >
Copy the code

2, the Map

Java.util.Map is defined by tags, which can have more than one child tag. Each entry contains a key and a value. The key must be defined in the tag. Because there is no restriction on the types of keys and values, you are free to specify,, or elements for them. You can define Map keys and values as attributes: simple constants are defined using keys and values; Bean references are defined through key-ref and value-ref attributes.

<bean id="cup" class="com.atguigu.spring.bean.Cup">
    <property name="bookMap">
        <map>
            <entry>
                <key>
                    <value>bookKey01</value>
                </key>
                <ref bean="book01"/>
            </entry>
            <entry>
                <key>
                    <value>bookKey02</value>
                </key>
                <ref bean="book02"/>
            </entry>
        </map>
    </property>
</bean>
Copy the code

3, the Properties

Use the definition java.util.properties, which uses more than one tag as a child tag. Each tag must define a key attribute

<bean class="com.atguigu.spring.bean.DataSource" id="dataSource">
    <property name="properties">
        <props>
            <prop key="userName">root</prop>
            <prop key="password">root</prop>
            <prop key="url">jdbc:mysql:///test</prop>
            <prop key="driverClass">com.mysql.jdbc.Driver</prop>
        </props>
    </property>
</bean>
Copy the code

4. Beans of collection type

If a collection object can only be configured inside a bean, the configuration of that collection cannot be reused. We need to take the configuration of the collection bean out for reference by other beans. Beans that configure collection types need to be imported into the util namespace

<util:list id="bookList">
    <ref bean="book01"/>
    <ref bean="book02"/>
    <ref bean="book03"/>
    <ref bean="book04"/>
    <ref bean="book05"/>
</util:list>

<util:list id="categoryList">
    <value>programming</value>
    <value>geek</value>
    <value>crosstalk</value>
    <value>Ballad singing</value>
</util:list>
Copy the code

2.4 Create beans from factories

2.4.1 Static Factory

Calling a static factory method to create a bean encapsulates the object creation process in a static method. When the client needs an object, it simply calls a static method and doesn’t care about the details of creating the object.

Declaring a bean created by a static method requires specifying the full name of the static factory class in the bean’s class property and the name of the factory method in the factory-method property. Finally, the element is used to pass the method parameters to the method.

Configuration Factory class:

/** * factory class for User object */
public class UserFactory {
    // Static method
    public static User getUser1(a) {
        return newUser(); }}Copy the code

The XML configuration:

<! Create user with static factory -->
<bean id="user1" class="ioc.service.UserFactory" factory-method="getUser1"></bean>
Copy the code

Class refers to the package path of the factory class, and factory-method refers to the static method of the factory class that creates the Bean. Note: Static methods must be used here

Testing:

@Test
public void testUser1(a){
    ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
    // Static factory creation
    User user1 = (User) context.getBean("user1");
    System.out.println("Static Factory Creation :" + user1);
}
Copy the code

Console output: static factory creation :ioc.pojo.User@3b088d51

2.4.2 Example Factory

Instance factory method: Encapsulates the creation of an object into a method of another object instance. When a client needs to request an object, it simply calls the instance method without worrying about the creation details of the object.

Implementation method: ① configure the bean of the factory class instance; ② Specify the name of the factory method in the factory-method attribute. ③ Pass method parameters to a factory method using the Construtor-arg element.

Configuration Factory class:

/** * factory class for User object */
public class UserFactory {
    // Common method
    public User getUser2(a) {
        return newUser(); }}Copy the code

The XML configuration:

<! Create user -->
<bean id="userFactory" class="ioc.service.UserFactory"></bean>
<bean id="user2" factory-bean="userFactory" factory-method="getUser2"></bean>
Copy the code

Testing:

@Test
public void testUser2(a){
    ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
    // The instance factory is created
    User user2 = (User) context.getBean("user2");
    System.out.println("Instance Factory creation :" + user2);
}
Copy the code

Console output: Instance factory creation :ioc.pojo.User@3b088d51

2.4.3 FactoryBean

There are two types of beans in Spring, ordinary beans and factory beans, or factoryBeans. Unlike regular beans, factory beans do not return an instance of the specified class. Instead, they return the object returned by the getObject method of the factory bean. Factory bean must implement org. Springframework. Beans. Factory. FactoryBean interface.

The first step is to create a class that acts as a FactoryBean and implements the interface FactoryBean

The second step implements the method in the interface, defining the returned bean type in the implemented method

public class MyBean implements FactoryBean<Course> {    Throws Exception {Course Course = new Course(); // 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; }}
Copy the code

The XML configuration:

<bean id="myBean" class="com.atguigu.spring5.factorybean.MyBean"></bean>
Copy the code

Testing:

@Testpublic void test3(a) {    ApplicationContext context = new ClassPathXmlApplicationContext("bean3.xml");    Course course = context.getBean("myBean", Course.class); System.out.println(course); }Copy the code

2.5 Advanced configuration of beans

2.5.1 Inheritance of Configuration Information

1. Background: Check the Employee configuration. The DEPT property is the same as the Employee configuration.

<bean id="dept" class="com.atguigu.parent.bean.Department">    <property name="deptId" value="100"/>    <property name="deptName" value="IT"/></bean><bean id="emp01" class="com.atguigu.parent.bean.Employee">    <property name="empId" value="1001"/>    <property name="empName" value="Tom"/>    <property name="age" value="20"/>    <! Duplicate attribute values -->	    <property name="detp" ref="dept"/></bean><bean id="emp02" class="com.atguigu.parent.bean.Employee">    <property name="empId" value="1002"/>    <property name="empName" value="Jerry"/>    <property name="age" value="25"/>    <! Duplicate attribute values -->    <property name="detp" ref="dept"/></bean>
Copy the code

2. Inheritance of configuration information

<! Emp01 as the parent bean, you can omit the configuration of the common attribute value.<bean id="emp02" parent="emp01">    <property name="empId" value="1002"/>    <property name="empName" value="Jerry"/>    <property name="age" value="25"/></bean>
Copy the code

Spring allows the configuration of beans to be inherited. The inherited bean is called the parent bean, and the bean that inherits from the parent bean is called the child bean. The child bean inherits configuration from the parent bean, including the bean’s property configuration, and the child bean can override the configuration inherited from the parent bean.

3. Supplementary notes

The parent bean can be used as a configuration template or as a bean instance. If you only want to use the parent bean as a template, you can set the abstract property to true so that Spring will not instantiate the bean.

If a bean’s class attribute is not specified, it must be abstract and not all attributes in the element will be inherited. For example: autowire, abstract, etc. You can also ignore the class attribute of the parent bean and have the child bean specify its own class and share the same property configuration. However, abstract must be set to true.

2.5.2 Dependencies between beans

Sometimes when a bean is created, another bean needs to be created. In this case, the preceding bean is said to have a dependency on the following bean. For example, the Department must be created when the Employee object is created. The important thing to note here is that a dependency is not a reference, and Employee can rely on the Department without referring to it.

<bean id="emp03" class="com.atguigu.parent.bean.Employee" depends-on="dept">    <property name="empId" value="1003"/>    <property name="empName" value="Kate"/>    <property name="age" value="21"/></bean>
Copy the code

2.5.3 Scope of beans

In Spring, you can set the scope of a bean in the scope attribute of an element to determine whether the bean is singleton or multi-instance. By default, Spring creates only one instance of each bean declared in the IOC container, which can be shared across the entire IOC container: all subsequent getBean() calls and bean references return this unique bean instance. This scope is called a Singleton, and it is the default scope for all beans.

When a bean is scoped as a singleton, Spring creates an object instance of the bean at the time the IOC container object is created. When the bean is scoped to prototype, the IOC container creates the instance object of the bean when it gets the instance of the bean.

2.5.4 Bean life cycle

1. The Spring IOC container manages the life cycle of beans. Spring allows specific tasks to be performed at specific points in the bean’s life cycle.

2. The Spring IOC container manages the bean lifecycle:

1) Create a bean instance through a constructor or factory method

2) Set values for bean properties and references to other beans

3) Call the bean’s initialization method

4) The bean is ready to use

5) When the container is closed, the bean’s destruction method is called

3. When configuring the bean, specify initialization and destruction methods for the bean using init-method and destroy-method properties

4. Backend handlers for beans

1) The bean post-processor allows additional processing of the bean before and after the initialization method is called

2) The bean post-processor treats all bean instances in the IOC container one by one, not a single instance. Typical applications are to check the correctness of bean properties or to change bean properties based on specific criteria.

3) rear bean processors need to implement interface: org. Springframework. Beans. Factory. Config. The BeanPostProcessor. Before and after the initialization method is called, Spring passes each bean instance to the following two methods of the interface:

Low postProcessBeforeInitialization (Object, String) : instantiation, dependency injection is completed, before the call display initialization for some custom initialization tasks

Low postProcessAfterInitialization (Object, String) : instantiation, dependency injection, the initialization is finished

The life cycle of the bean after adding the bean post-processor

1) Create a bean instance through a constructor or factory method

2) Set values for bean properties and references to other beans

3) pass bean instance to rear bean processors postProcessBeforeInitialization * * * * method ()

4) Call the bean’s initialization method

5) pass bean instance to rear bean processors * * postProcessAfterInitialization () method

6) The bean is ready to use

7) Call the bean’s destruction method when the container is closed

6. Custom post-processor demo

1) Custom processor

package com.dpb.processor;import org.springframework.beans.BeansException;import org.springframework.beans.factory.config.BeanPostProcessor;The BeanPostProcessor interface is used to add our own logic before and after bean instantiation, configuration, and other initialization methods ** /public class MyBeanPostProcessor implements BeanPostProcessor{    /** * Complete some custom initialization tasks before calling display initialization * Note: Method return value cannot be null * If null is returned then subsequent initializers will either report a null pointer exception or the bena instance object cannot be retrieved through the getBean() method */ because the backend handler took the bean instance object from the Spring IoC container and did not put it back into the IoC container */    @Override    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {        System.out.println("Initialize before-- instantiated bean object :"+bean+"\t"+beanName);        // Different beanName processing operations can be performed on the return bean; } /** * execute when instantiation, dependency injection, initialization is complete Method return value cannot be null * If null is returned then subsequent initializers will either report a null pointer exception or the bena instance object cannot be retrieved through the getBean() method */ because the backend handler took the bean instance object from the Spring IoC container and did not put it back into the IoC container */ @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {system.out.println (" Initialize after... Instantiated bean object :"+bean+"\t"+beanName); // Different beanName processing operations can be performed on the return bean; }}
Copy the code

Note: The two methods in the interface cannot return NULL. If null is returned, the subsequent initialization method will either report a null pointer exception or fail to get the bena instance object through the getBean() method, because the backend processor did not put the bean instance object back into the IoC container after fetching it from the Spring IoC container

2) pojo class

public class User {	private int id;	private String name;	private String beanName;		public User(a){		System.out.println("User is instantiated");	}	public int getId(a) {		return id;	}	public void setId(int id) {		this.id = id;	}	public String getName(a) {		return name;	}	public void setName(String name) {		System.out.println("Setup:"+name);		this.name = name;	}	public String getBeanName(a) {		return beanName;	}	public void setBeanName(String beanName) {		this.beanName = beanName;	}	/** * Custom initialization method */	public void start(a){		System.out.println("Custom initialization methods in User");	}}
Copy the code

3) Configuration file registration


      <beans xmlns="http://www.springframework.org/schema/beans"       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">    <bean class="com.dpb.pojo.User" id="user" init-method="start">        <property name="name" value="Bobo Duck" />    </bean>    <! -- Register handler -->    <bean class="com.dpb.processor.MyBeanPostProcessor"></bean></beans>
Copy the code

4) test

@Testpublic void test(a) {    ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml"); User user = ac.getBean(User.class); System.out.println(user); }Copy the code

5) Output results

User is instantiated setting: bobo duck initialization before– instantiated bean object :com.dpb.pojo.User@65e2dbf3 User User custom initialization method initialization after… Instantiated bean object :com.dpb.pojo.User@65e2dbf3 user com.dpb.pojo.User@65e2dbf3

Attention!!

BeanFactory and ApplicationContext containers treat bean postprocessors slightly differently. The ApplicationContext container automatically detects that the Beans in the Spring configuration file correspond to Java classes that implement the BeanPostProcessor interface and automatically registers them as post-processors. They are called during bean creation, so deploying a post-processor is not much different from regular beans. The BeanFactory container must register the bean post-processor through the registration shown in the code, which is defined in the ConfigurableBeanFactory interface in the IoC container inheritance architecture. The test code is as follows:

@Testpublic void test2(a) {    //ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml"); XmlBeanFactory bf = new XmlBeanFactory(new ClassPathResource("applicationContext.xml")); / / show add post processor bf. AddBeanPostProcessor (bf) getBean (MyBeanPostProcessor. Class)); User user = bf.getBean(User.class); System.out.println(user); }
Copy the code

7. Multiple rear processors

We can add multiple BeanPostProcessor interface implementation classes to the Spring configuration file, which by default are called by the Spring container in the order in which the postprocessor is defined.

In the Spring mechanism, you can specify the post-processor call order by having the BeanPostProcessor interface implementation class implement the Ordered interface getOrder method, which returns an integer with a default value of 0 and the highest priority, and the higher the priority, the lower the priority.

public class MyBeanPostProcessor implements BeanPostProcessor.Ordered{    @Override    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {        System.out.println("A before-- instantiated bean object :"+bean+"\t"+beanName);        // Different beanName processing operations can be performed on the return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("A after... Instantiated bean object :"+bean+"\t"+beanName); // Different beanName processing operations can be performed on the return bean; } @Override public int getOrder() { // TODO Auto-generated method stub return 10; }}
Copy the code
public class MyBeanPostProcessor2 implements BeanPostProcessor.Ordered{    @Override    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {        System.out.println("B before-- instantiated bean object :"+bean+"\t"+beanName);        // Different beanName processing operations can be performed on the return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("B after... Instantiated bean object :"+bean+"\t"+beanName); // Different beanName processing operations can be performed on the return bean; } @Override public int getOrder() { // TODO Auto-generated method stub return 2; }}
Copy the code

Test output:

User is instantiated: B before– instantiated bean object :com.dpb.pojo.User@7fac631b user A before– instantiated bean object :com.dpb.pojo.User@7fac631b user user A custom initialization method B after… Instantiated bean object :com.dpb.pojo.User@7fac631b user A after… Instantiated bean object :com.dpb.pojo.User@7fac631b user com.dpb.pojo.User@7fac631b

2.5.5 Referencing External Properties Files

As the bean configuration information grows, it becomes more difficult to find and modify the configuration information of some beans. In this case, part of the information can be extracted outside the bean configuration file, stored in the properties format of the property file, and the content of the properties property file can be referenced in the bean configuration file, so that only the properties property file can be modified when some property values change. This technique is mostly used to configure basic information to connect to a database.

1. Direct configuration

<! -- Direct configuration --><bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">    <property name="user" value="root"/>    <property name="password" value="root"/>    <property name="jdbcUrl" value="jdbc:mysql:///test"/>    <property name="driverClass" value="com.mysql.jdbc.Driver"/></bean>
Copy the code

2. Create the Properties file

prop.userName=rootprop.password=rootprop.url=jdbc:mysql:///testprop.driverClass=com.mysql.jdbc.Driver
Copy the code

3. Introduce the context namespace

4, specify the location of the properties file

<! Specify the location of the properties file --><! -- classpath: XXX indicates that the properties file is in the classpath --><context:property-placeholder location="classpath:jdbc.properties"/>
Copy the code

5. Import property values from the Properties properties file

<! Import property values from the properties file --><bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">    <property name="user" value="${prop.userName}"/>    <property name="password" value="${prop.password}"/>    <property name="jdbcUrl" value="${prop.url}"/>    <property name="driverClass" value="${prop.driverClass}"/></bean>
Copy the code

2.6 Automatic Assembly

2.6.1 Concept of automatic assembly

1. Manual assembly: the attribute values are specified explicitly in the form of value or ref.

2. Autowiring: According to the specified assembly rules, Spring automatically injects matching property values into the bean without specifying them explicitly.

2.6.2 Assembly mode

1. Autown-by-type: Inject a type-matching bean as a property into another bean. If there are multiple beans in the IOC container that are of the same type as the target bean, Spring will not be able to determine which bean is the best fit for this property, and therefore cannot perform autoassembly

2. Autowiring by Name: The name of the target bean and the property name must be set exactly the same

3. Autowiring by constructors: This autowiring method can be complicated when there are multiple constructors in the bean. Not recommended.

2.6.3 Selection suggestions

Compared to annotated autowiring, autowiring in XML documents is a bit unwieldy, and annotated autowiring is more common in projects.

2.6.4 Demonstrate the automatic assembly process

1. Automatic injection based on the property name

<! ByName = byName; byType = byType; bytowire = byType;<bean id="emp" class="com.atguigu.spring5.autowire.Emp" autowire="byName">    <! --<property name="dept" ref="dept"></property>--></bean> <bean id="dept" class="com.atguigu.spring5.autowire.Dept"></bean> 
Copy the code

2. Automatic injection based on the property type

<! ByName = byName; byType = byType; bytowire = byType;<bean id="emp" class="com.atguigu.spring5.autowire.Emp" autowire="byType">    <! --<property name="dept" ref="dept"></property>--></bean> <bean id="dept" class="com.atguigu.spring5.autowire.Dept"></bean>
Copy the code

2.7 SpEL

2.7.1 profile

Spring Expression Language Spring Expression Language (SpEL) Runtime queries are supported and object graphs can be manipulated.

Like EL expressions on JSP pages and OGNL expressions used in Struts2, SpEL accesses the object graph based on properties defined by Javabean-style getXxx() and setXxx() methods, completely in line with familiar operation habits.

2.7.2 Basic Syntax

Use SpEL * * # {… }** as a delimiter, all characters in the big box number will be considered SpEL expressions.

2.7.3 Using Literals

Low integer:

Low decimal Numbers:

● Scientific counting method:

● String literals can be delimited by single or double quotation marks

The < property name = “name” value = “# {‘ Chuck ‘}” / >

<property name=’name’ value=‘#{“Chuck”}’/>

Low Boolean:

2.7.4 Referencing Other Beans

<bean id="emp04" class="com.atguigu.parent.bean.Employee">    <property name="empId" value="1003"/>    <property name="empName" value="Kate"/>    <property name="age" value="21"/>    <property name="detp" value="#{dept}"/></bean>
Copy the code

2.7.5 Reference the property value of another bean as the value of one of its own properties

<bean id="emp05" class="com.atguigu.parent.bean.Employee">    <property name="empId" value="1003"/>    <property name="empName" value="Kate"/>    <property name="age" value="21"/>    <property name="deptName" value="#{dept.deptName}"/></bean>
Copy the code

2.7.6 Calling a Non-static Method

<! Create an object and call the method of this object in SpEL expression.<bean id="salaryGenerator" class="com.atguigu.spel.bean.SalaryGenerator"/><bean id="employee" class="com.atguigu.spel.bean.Employee">    <! Assign a property from the return value of the object method -->    <property name="salayOfYear" value="#{salaryGenerator.getSalaryOfYear(5000)}"/></bean>
Copy the code

2.7.7 Calling a Static Method

<bean id="employee" class="com.atguigu.spel.bean.Employee">    <! Call class static methods in SpEL expressions -->    <! --T() is the full class name -->    <property name="circle" value="#{T(java.lang.Math).PI*20}"/></bean>
Copy the code

2.7.8 operator.

1, arithmetic operators: +, -, *, /, %, ^

2, string connection: +

3, comparison operators: <, >, ==, <=, >=, lt, gt, eq, LE, GE

4, logical operators: and, or, not, |

5, ternary operator: judgment condition? Value when the result is true: Value when the result is false

Matches (matches)

2.8 Using Annotations

2.8.1 overview

Compared with XML, configuring beans through annotations is more concise and elegant, and fits well with the concept of MVC componentization development. It is commonly used in development.

2.8.2 Using annotations to identify components

1. Common Component: @Component

Identifies a component managed by the Spring IOC container

2. Persistence layer component: @respository

Identifies a persistence layer component managed by the Spring IOC container

3. Business logic layer component: @service

Identifies a business logic layer component managed by the Spring IOC container

4. Presentation layer Controller component: @controller

Identifies a presentation layer controller component managed by the Spring IOC container

5. Component naming rules

1) The default is to use a string lowercase from the component’s simple class name as the bean ID

2) Specify the bean ID using the value attribute of the component annotation

@Respository("bookdaocxc")@scope (value = "prototype")public class BookDao() {}
Copy the code

Note: In fact, Spring does not have the ability to recognize whether a component is of the type it marks, even if the @respository annotation is applied to a presentation controller component without causing any errors. So the @respository, @service, and @Controller annotations are just for the developer to know for himself what role the current component plays.

2.8.3 Scanning Components

Components identified by the above annotations also need to be scanned by Spring to detect them.

1. Specify the package to be scanned

<context:component-scan base-package="com.atguigu.component"/>
Copy the code

2. Elaborate

1) The base-package property specifies a base class package that needs to be scanned. Spring will scan all classes in this base class package and its subpackages.

2) When multiple packets need to be scanned, separate them with commas.

3) If you want to scan only specific classes instead of all classes in the base package, you can use the Resource-pattern attribute to filter specific classes. Example:

<context:component-scan                         base-package="com.atguigu.component"                         resource-pattern="autowire/*.class"/>
Copy the code

4) Include and exclude

● Context :include-filter the child node represents the target class to include

Note: You usually need to use this in conjunction with the use-default-filters property to achieve the “only some components” effect. By setting the use-default-filters property to false, the default filters are disabled and only the components specified by the rule in include-filter are scanned.

● Context :exclude-filter The child node represents the target class to exclude

● Component-scan can have several include-filter and exclude-filter child nodes

● Filter expression

category The sample instructions
annotation com.atguigu.XxxAnnotation Filter all classes that annotate xxxannotations. This rule filters based on whether the target component is annotated with the specified type of annotation.
assignable com.atguigu.BaseXxx Filter all subclasses of the BaseXxx class. This rule filters based on whether the target component is a subclass of the specified type.
aspectj com.atguigu.*Service+ All class names end with Service, or subclasses of such a class. This rule is filtered based on AspectJ expressions.
regex com.atguigu.anno.* All classes under the com.atguigu.anno package. This rule filters based on the name of the class that the regular expression matches.
custom com.atguigu.XxxTypeFilter Use the XxxTypeFilter class to customize filtering rules by encoding them. The class must implement the org. Springframework. Core. The filter. The TypeFilter interface
<! -- example 1 use-default-filters="false" -- filter context:include-filter ="false" --><context:component-scan base-package="com.atguigu" use-default-filters="false">    <context:include-filter type="annotation"                             expression="org.springframework.stereotype.Controller"/></context:component-scan><! -- Example 2 context:exclude-filter, set which content is not scanned --><context:component-scan base-package="com.atguigu">    <context:exclude-filter type="annotation"                             expression="org.springframework.stereotype.Controller"/></context:component-scan>
Copy the code

3, the JAR package

You must import another JAR package from the original combination: Spring-aOP-4.0.0.release.jar

2.8.4 Assembling components

1, requirements,

The Controller component requires an instance of the Service component, and the Service component requires an instance of the Repository component. Spring can help us with the assembly of properties through annotations.

2. Implementation basis

In designated to scan the package, the context: component – scan elements will automatically register a beans rear processor: AutowiredAnnotationBeanPostProcessor instance. The backend processor can automatically assemble attributes annotated with @AutoWired, @Resource, or @Inject.

3. @autowired annotations

1) Automatic assembly is realized according to type.

2) Constructors, ordinary fields (even if non-public), and any method with parameters can apply the @AutoWired annotation

3) By default, all attributes that use the @AutoWired annotation need to be set. When Spring does not find a matching bean assembly property, it throws an exception.

4) If a property is not allowed to be set, you can set the @AutoWired annotation’s required property to false

5) By default, when there are multiple type-compatible beans in the IOC container, Spring tries to match whether the bean ID value is the same as the variable name, and assembs the bean if they are. Autowiring by type will not work if the bean ID value is not the same. At this point, you can provide the bean name in the @Qualifier annotation. Spring even allows the @qualifiter annotation on method parameters to specify the name of the injected bean.

6) The @autoWired annotation can also be applied to properties of array types, in which case Spring will automatically assemble all matching beans.

7) The @AutoWired annotation can also be applied to collection properties, where Spring reads the collection’s type information and then automatically assembles all compatible beans.

8) When the @autowired annotation is used on java.util.map, if the Map’s key is String, Spring will automatically assemble a value type-compatible bean as the value and use the bean’s ID value as the key.

4, @ the Resource

The @Resource annotation requires an attribute of the bean name, and if this attribute is empty, the variable or method name at the annotation is automatically adopted as the bean name.

5, @ Inject

The @inject, like the @resource annotation, Inject matched beans by type, but without the reqired attribute.

/** Implement attribute injection based on annotations@Autowired: The first step is to create the Service and DAO objects and add annotations to the Service and DAO classes. The second step is to inject dao objects into the Service and add DAO type attributes to the service class. Use the annotation */ on attributes@Servicepublic class UserService {    @autoWired Private UserDao UserDao; public void add() { System.out.println("service add......." ); userDao.add(); }} @qualifier Inject the use of the @Qualifier annotation by name, @qualifier (value = "userDaoImpl1"); @qualifier (value = "userDaoImpl1"); Private UserDao UserDao; /** 3, @resource: @resource (name = "userDaoImpl1") // Inject by name private UserDao UserDao; */ @value (Value = "ABC ")private String name; // (1) create a Configuration class instead of the XML Configuration file @configuration // as a Configuration class, @componentScan (basePackages = {"com.atguigu"})public class SpringConfig {} @testPublic void TestService2 () {/ / loading configuration class ApplicationContext context = new AnnotationConfigApplicationContext (SpringConfig. Class); UserService userService = context.getBean("userService", UserService.class); System.out.println(userService); userService.add(); }
Copy the code

2.9 Generic dependency injection

2.9.1 profile

In Spring 4.x, you can inject a reference to a member variable of a generic type corresponding to a subclass

2.9.2 implementation

Component base classes

public class BaseRepository<T> {    public void save(a) {        System.out.println("Saved by BaseRepository");    }}public class BaseService<T> {    @Autowired    private BaseRepository<T> repository;    public void add(a) {        repository.save();    }}
Copy the code

Component entity classes

@Repositorypublic class UserRepository extends BaseRepository<User>{    public void save(a) {        System.out.println("Saved by UserRepository");    }}@Servicepublic class UserService extends BaseService<User>{}
Copy the code

Model entity classes

public class User {}
Copy the code

4, test,

ApplicationContext ioc = new ClassPathXmlApplicationContext("di.xml"); UserService us = (UserService) ioc.getBean("userService"); us.add();//Saved by UserRepository
Copy the code

2.10 Consolidating Multiple Configuration Files

1. Spring allows configuration file integration by importing multiple configuration files into a single file. So when you start the Spring container, you only need to specify the combined configuration file.

The resource attribute of the import element supports Spring’s standard path resources

Three, AOP overview

3.1 summary of AOP

1, AOP(aspect-oriented Programming) : is a new methodology, is the traditional OOP(Object-oriented Programming, object-oriented Programming) supplement.

2. The primary object of AOP programming operations is aspects, which modularize crosscutting concerns.

3. When applying AOP programming, you still need to define common functionality, but you can clearly define where and how that functionality is applied without modifying the affected classes. This allows cross-cutting concerns to be modularized into special classes — classes that are often referred to as “facets.”

4. Benefits of AOP:

1) Each thing logic is located in one location, the code is not scattered, easy to maintain and upgrade

2) The business module is more concise and only contains the core business code

3.2 AOP terminology

3.2.1 Crosscutting Concerns

The same class of non-core business extracted from each method.

3.2.2 section (Aspect)

A class that encapsulates information about crosscutting concerns, each represented as a notification method.

3.2.3 notice (Advice)

The specific work that must be done in the section

3.2.4 the Target (Target)

The notified object

3.2.5 agent (Proxy)

The proxy object created after the notification is applied to the target object

3.2.6 Connecting Points (Joinpoint)

Crosscutting concerns are embodied in program code at a particular point in program execution. For example, before or after a class method is called, or after the method catches an exception. You can use horizontal and vertical coordinates to locate a specific join point in your application.

3.2.7 Pointcut:

The manner in which connection points are positioned. Each class has multiple join points in its methods, so join points are an objective thing in a class. If you think of join points as records in a database, pointcuts are query criteria that AOP can use to locate specific join points. Tangent point by org. Springframework.. Aop Pointcut interface is described, it USES as a condition of the join query classes and methods.

3.3 the AspectJ

3.3.1 profile

AspectJ: The most complete and popular AOP framework in the Java community. In Spring2.0 and above, you can use aspectj-based annotations or xml-based configuration AOP.

3.3.2 Enable AspectJ annotation support in Spring

1. Import the JAR package

1) aopalliance. Jar

. 2) the aspectj weaver. The jar

3) the spring – aspects. The jar

2. Introduce aop namespaces

3, configuration,

< AOP: Aspectj-AutoProxy > : When the Spring IOC container detects the < AOP: Aspectj-AutoProxy > element in the bean configuration file, it automatically creates a proxy for beans that match the AspectJ aspect

3.3.3 Declare aspects with AspectJ annotations

1. To declare AspectJ facets in Spring, simply declare the facets as bean instances in the IOC container.

2. After the AspectJ aspect is initialized in the Spring IOC container, the Spring IOC container creates proxies for beans that match the AspectJ aspect.

3. In AspectJ annotations, a section is just a Java class annotated with @Aspect, which tends to contain a lot of advice.

Notifications are simple Java methods that indicate some kind of annotation.

AspectJ supports five types of notification annotations:

1) @before: pre-notification, executed Before method execution

2) @after: post-notification, executed After method execution

3) @afterRETURNING: Return notification, executed after method returns results

4) @afterThrowing: exception notification, executed after a method throws an exception

5) @around: Circular notification, executed Around a method

6. AOP manipulation (AspectJ annotations)

Public class User {public void add() {system.out.println ("add.......") ); }}// (1) create a method in the class. Public class UserProxy {public void before() {// Before system.out.println ("before......") ); }}
Copy the code
<! In the Spring configuration file, enable annotation scanning -->
      <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 http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">    <! -- Enable annotation scan -->    <context:component-scan base-package="com.atguigu.spring5.aopanno"></context:component-scan>
Copy the code
@componentPublic class User {} @componentPublic class UserProxy { Public class UserProxy {} public class UserProxy {} public class UserProxy {}
Copy the code
<! -- Enable proxy object generation in spring configuration file --><! -- Enable Aspect generation proxy object --><aop:aspectj-autoproxy></aop:aspectj-autoproxy>
Copy the code
// Add a notification type annotation to the notification method in the enhanced class. Use pointcut expressions to configure // enhanced class @Component@Aspect // to generate proxy objects public Class UserProxy {// pre-notification // @before annotation is expressed as pre-notification @before (value = "execution(* com.atguigu.spring5.aopanno.User.add(..) )") public void before() { System.out.println("before........." ); } / / rear notice (return) @ AfterReturning (value = "execution (* com. Atguigu. Spring5. Aopanno. User. The add (..) )") public void afterReturning() { System.out.println("afterReturning........." ); } / / final notice @ After (value = "execution (* com. Atguigu. Spring5. Aopanno. User. The add (..) )") public void after() { System.out.println("after........." ); } / / exception notification @ AfterThrowing (value = "execution (* com. Atguigu. Spring5. Aopanno. User. The add (..) )") public void afterThrowing() { System.out.println("afterThrowing........." ); } / / notify @ Around round (value = "execution (* com. Atguigu. Spring5. Aopanno. User. The add (..) )") public void around(ProceedingJoinPoint ProceedingJoinPoint) throws Throwable {system.out.println (" surround before.........") ); / / be enhanced method performs proceedingJoinPoint. Proceed (); System.out.println(" surround after........." ); }} / / 5, the same point extraction / / the same entry point to extract the @pointcut (value = "execution (* com. Atguigu. Spring5. Aopanno. User. The add (..) @before (value = "pointdemo()")public void Before() { System.out.println("before........." ); }// set the priority of the enhancement class to @order (numeric type value) @Component@Aspect @order (1)public class PersonProxy {}// No need to create XML configuration file @Configuration@ComponentScan(basePackages = {"com.atguigu"}) @enableAspectJAutoProxy (proxyTargetClass = true)public class ConfigAop {}
Copy the code

7. AOP operations (AspectJ configuration files)

<! Create two class objects in the spring configuration file.<! Create object --> <bean id="book" class="com.atguigu.spring5.aopxml.Book"></bean> <bean id="bookProxy" class="com.atguigu.spring5.aopxml.BookProxy"></bean> <! Configure pointcuts in the Spring configuration file --> <! Configure AOP enhancement --><aop:config>    <! -- entry point -->    <aop:pointcut id="p" expression="execution(* com.atguigu.spring5.aopxml.Book.buy(..) )"/>    <! -- Configuration section -->    <aop:aspect ref="bookProxy">        <! -- Enhancing effect in specific methods -->        <aop:before method="before" pointcut-ref="p"/>    </aop:aspect></aop:config>
Copy the code

Four, AOP details

4.1 Pointcut Expressions

1,

Locate one or more specific join points by means of expressions.

2. Grammatical details

1) Syntax format of pointcut expressions

Execution ([permission modifier] [return value type] [simple class name/full class name] method name ([parameter list]))

2) Give some examples

expression meaning
execution(* com.atguigu.spring.ArithmeticCalculator.*(..) ) All methods declared in the ArithmeticCalculator interface. The first “*” represents any modifier and any return value. The second “*” stands for any method. “..” Matches any number of parameters of any type. You can omit the package name if the target class, interface and the facet class are in the same package.
execution(public * ArithmeticCalculator.*(..) ) All public methods of the ArithmeticCalculator interface
execution(public double ArithmeticCalculator.*(..) ) Method in the ArithmeticCalculator interface that returns a value of type double
execution(public double ArithmeticCalculator.*(double, ..) ) A method whose first argument is of type double. “..” Matches any number of parameters of any type.
execution(public double ArithmeticCalculator.*(double, double)) The argument type is double, a method of type double
execution (* .add(int,..) ) || execution( *.sub(int,..) ) Add or sub method in any class whose first argument is int

3) in AspectJ, point expression can pass “&”, “| |”, “!” And so on.

4.2 Details of current connection points

2 an overview

Pointcut expressions typically position a set of methods at a macro level and, combined with annotations for a specific notification, determine the corresponding join points. For a specific join point, we might care about some specific information about the join point, such as the method name of the current join point, the parameter values currently passed in, and so on. This information is encapsulated in the JoinPoint instance object.

4.2.2 JoinPoint

4.3 notice

This overview

1. The operation to be performed at the specific join point.

2. A facet can contain one or more notifications.

3. The value of the annotation used by the advice is often a pointcut expression.

4.3.2 Pre-notification

Pre-notification: notification executed before method execution

2. Use the @before annotation

4.3.3 Post Notification

Post-notification: Post-notification is executed after the join point has completed, when the join point returns a result or throws an exception

L Use the @after annotation

4.3.4 Return notification

Return notification: Postnotification is executed whether the join point returns normally or throws an exception. If you want to log only when the join point returns, use return notifications instead of post notifications.

2. Use @afterreturning annotations

Access the return value of the join point in the return notification

1) In the return notification, you can access the return value of the join point by adding the RETURNING attribute to the @AfterRETURNING annotation. The value of this property is the name of the parameter to pass in the return value

2) You must add a parameter of the same name to the signature of the notification method. Spring AOP passes the return value through this parameter at run time

3) The original pointcut expression needs to appear in the pointcut property

4.3.5 Exception Notification

Exception notification: Exception notification is performed only if the join point throws an exception

2. Add the Throwing attribute to the @AfterThrowing annotation to also access exceptions thrown by join points. Throwable is the top-level parent of all error and exception classes, so any errors and exceptions can be caught in the exception notification method.

3. If you are only interested in a particular exception type, you can declare the parameter as the parameter type of other exceptions. Notifications are then executed only when exceptions of this type and its subclasses are thrown

4.3.6 Surround notification

1. Wrap notifications are the most powerful of all notification types, giving you complete control over join points and even whether they are executed.

2. For surround notifications, the join point parameter type must be ProceedingJoinPoint. It is a subinterface of JoinPoint and allows you to control when and if join points are executed.

The ProceedingJoinPoint method proceed() needs to be explicitly called in the surround notification to execute the propped method. Forgetting to do so would result in the notification being executed, but the target method was not.

4. Note that the method surrounding the notification needs to return the result of the target method’s execution, that is, calling joinPoint.proceed(); Otherwise a null pointer exception will occur.

4.3.7 Reusing pointcut definitions

1. When writing AspectJ facets, you can write pointcut expressions directly in the notification annotations. But the same pointcut expression can be repeated in multiple notifications.

2. In AspectJ facets, you can declare a Pointcut as a simple method with the @Pointcut annotation. The method body of a pointcut is usually empty because it makes no sense to mix the pointcut definition with the application logic.

The access controller for a pointcut method also controls the visibility of that pointcut. If pointcuts are to be used across multiple facets, it is best to centralize them in a common class. In this case, they must be declared public. When introducing this pointcut, you must also include the class name. If the class is not in the same package as the aspect, you must also include the package name.

4. Other notifications can introduce this pointcut through the method name

4.3.8 Specify the priority of the section

When more than one aspect is applied to the same join point, their priority is uncertain unless explicitly specified.

2. The priority of the aspect can be specified by implementing the Ordered interface or using the @Order annotation.

3. Implement Ordered interface, the smaller the return value of getOrder(), the higher the priority.

4. With the @order annotation, the ordinal number appears in the annotation

Configure the facets in XML

5.1 an overview of the

In addition to declaring aspects using AspectJ annotations, Spring also supports declaring aspects in bean configuration files. This declaration is done through XML elements in the AOP namespace.

Normally, annotation-based declarations take precedence over XML-based declarations. Aspects are aspectJ-compliant through AspectJ annotations, and XML-based configuration is proprietary to Spring. As AspectJ is increasingly supported by AOP frameworks, there will be more opportunities for reuse of aspects written in an annotated style.

5.2 Configuration Details

In the Bean configuration file, all Spring AOP configurations must be defined inside the < AOP :config> element. For each aspect, an AOP: Aspect element is created to reference the back-end bean instance for the specific aspect implementation.

The aspect bean must have an identifier that can be referenced by the AOP :aspect element.

5.3 Declaring pointcuts

Pointcuts use < AOP :pointcut> element declarations.

Pointcuts must be defined under the < AOP :aspect> element, or directly under the < AOP :config> element.

1) Defined under the < AOP :aspect> element: only valid for the current aspect

2) Defined under the <aop:config> element: valid for all facets

3. Xml-based AOP configurations do not allow names to reference other pointcuts in pointcut expressions.

5.4 Declaration Notice

1. In an AOP namespace, each notification type corresponds to a specific XML element.

Notification elements need to be used to reference pointcuts or to embed pointcut expressions directly.

The method property specifies the name of the notification method in the aspect class


      <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 http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd">    <! Annotation based AOP steps; Add both the target class and the aspect class to the IOC container. @Component 2. Tell Spring which is the aspect class. Use five notification annotations in the Aspect class to configure when and where these notification methods run in the Aspect.    <! -- Enable annotation based AOP functionality; Aop namespace -->    <! AOP based on configuration    <bean id="myMathCalculator" class="com.atguigu.impl.MyMathCalculator"></bean>    <bean id="BValidateApsect" class="com.atguigu.utils.BValidateApsect"></bean>    <bean id="logUtils" class="com.atguigu.utils.LogUtils"></bean>    <! -- Need AOP namespace -->    <aop:config>        <aop:pointcut expression="execution(* com.atguigu.impl.*.*(..) )" id="globalPoint"/>        <! - ordinary pre = = = = = the target method = = = = = (returns) on the rear/round = = = = s common rear = = = = average return - >        <! -- Specify section: @aspect -->        <aop:aspect ref="logUtils" order="1">            <! -- The current section is available -->            <aop:around method="myAround" pointcut-ref="mypoint"/>            <aop:pointcut expression="execution(* com.atguigu.impl.*.*(..) )" id="mypoint"/>            <! Configure which method is pre-notification; Method specifies the method name -->            <aop:before method="logStart" pointcut="execution(* com.atguigu.impl.*.*(..) )"/>            <aop:after-returning method="logReturn" pointcut-ref="mypoint" returning="result"/>            <aop:after-throwing method="logException" pointcut-ref="mypoint" throwing="exception"/>            <aop:after method="logEnd" pointcut-ref="mypoint"/>        </aop:aspect>        <aop:aspect ref="BValidateApsect" order="3">            <aop:before method="logStart" pointcut-ref="globalPoint"/>            <aop:after-returning method="logReturn" pointcut-ref="globalPoint" returning="result"/>            <aop:after-throwing method="logException" pointcut-ref="globalPoint" throwing="exception"/>            <aop:after method="logEnd" pointcut-ref="globalPoint"/>        </aop:aspect>        <! Use five notification annotations in the aspect class to configure when and where the notification methods in the aspect run.    </aop:config>    <! -- Notes: quick and convenient configuration: perfect function; Important configuration, not important annotations; --></beans>
Copy the code

Six, JdbcTemplate

6.1 an overview of the

To make JDBC easier to use, Spring defines an abstraction layer on top of the JDBC API to build a JDBC access framework.

At the heart of the Spring JDBC framework, JDBC templates are designed to provide template methods for different types of JDBC operations in a way that minimizes database access while preserving as much flexibility as possible.

Spring’s JdbcTemplate can be thought of as a small, lightweight persistence layer framework, very close to the DBUtils style we’ve used before.

6.2 Environment Preparation

6.2.1 Importing JAR Packages

1. JAR packages required by IOC containers

Commons logging – 1.1.1. The jar

Spring beans – 4.0.0. RELEASE. The jar

Spring – the context – 4.0.0. RELEASE. The jar

Spring – the core – 4.0.0. RELEASE. The jar

Spring – expression – 4.0.0. RELEASE. The jar

JdbcTemplate JAR package

Spring – JDBC – 4.0.0. RELEASE. The jar

Spring – the orm – 4.0.0. RELEASE. The jar

Spring – tx – 4.0.0. RELEASE. The jar

3. Database drivers and data sources

C3p0-0.9.1.2. Jar

Mysql connector – Java – 5.1.7 – bin. The jar

6.2.2 Creating a Property file for Basic Database Information

user=rootpassword=rootjdbcUrl=jdbc:mysql:///query_datadriverClass=com.mysql.jdbc.DriverinitialPoolSize=30minPoolSize=10maxPoo lSize=100acquireIncrement=5maxStatements=1000maxStatementsPerConnection=10
Copy the code

6.2.3 Configuring related beans in the Spring configuration file

1. Data source object

<context:property-placeholder location="classpath:jdbc.properties"/><bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">    <property name="user" value="${user}"/>    <property name="password" value="${password}"/>    <property name="jdbcUrl" value="${jdbcUrl}"/>    <property name="driverClass" value="${driverClass}"/>    <property name="initialPoolSize" value="${initialPoolSize}"/>    <property name="minPoolSize" value="${minPoolSize}"/>    <property name="maxPoolSize" value="${maxPoolSize}"/>    <property name="acquireIncrement" value="${acquireIncrement}"/>    <property name="maxStatements" value="${maxStatements}"/>    <property name="maxStatementsPerConnection" value="${maxStatementsPerConnection}"/></bean>
Copy the code

2. JdbcTemplate object

<bean id="template" class="org.springframework.jdbc.core.JdbcTemplate">    <property name="dataSource" ref="dataSource"/></bean>
Copy the code

6.3 Persistency Operations

6.3.1 increase deletion

JdbcTemplate.update(String, Object…)

6.3.2 Batch add, delete and modify

JdbcTemplate.batchUpdate(String, List<Object[]>)

Object[] encapsulates the parameters required for each execution of an SQL statement

The List collection encapsulates all the parameters of the SQL statement when it is executed multiple times

6.3.3 Querying a Single Row

JdbcTemplate.queryForObject(String, RowMapper, Object…)

6.3.4 Querying Multiple Rows

JdbcTemplate.query(String, RowMapper, Object…)

RowMapper objects can still use BeanPropertyRowMapper

6.3.5 Querying a Single Value

JdbcTemplate.queryForObject(String, Class, Object…)

6.4 JdbcTemplate with named Parameters

6.4.1 About Named Parameters

We have experienced the use of named parameters in Hibernate HQL queries. Compared with location-based parameters, named parameters have better maintainability and can be considered in SQL statements with a large number of parameters.

In the Spring can be used by NamedParameterJdbcTemplate objects of a class with a named parameter SQL statements.

6.4.2 create NamedParameterJdbcTemplate object through the IOC container

<! -- JDBCTemplate class object that can use named parameters --><bean id="namedTemplate"       class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">    <! -- No no-argument constructor, must pass in data source or JdbcTemplate object -->    <constructor-arg ref="dataSource"/></bean>
Copy the code

6.4.3 Format of named Parameters in SQL Statements

INSERT INTO depts (dept_name) VALUES (:deptName)
Copy the code

6.4.4 Passing in named Parameters

1. Pass it through the Map object

NamedParameterJdbcTemplate.update(String, Map<String, ? >)

Map keys are parameter names and values are parameter values

2. Pass in the SqlParameterSource object

String sql = "INSERT INTO depts (dept_name) VALUES (:deptName)"; Department department =new Department(null."YYY".null); SqlParameterSource sqlParameterSource =newBeanPropertySqlParameterSource(department); namedTemplate.update(sql, sqlParameterSource);Copy the code

6.5 Implementing Dao using JdbcTemplate

6.5.1 Automatic injection through the IOC container

The JdbcTemplate class is thread-safe, so you can declare a single instance of it in the IOC container and inject that instance into all Dao instances.

@Repositorypublic class EmployeeDao {    @Autowired    private JdbcTemplate jdbcTemplate;    public Employee get(Integer id){        //…    }}
Copy the code

6.5.2 Extending the JdbcDaoSupport class

/** ** not recommended */@Repositorypublic class DepartmentDao extends JdbcDaoSupport{    @Autowired    public void setDataSource2(DataSource dataSource){        // The setDataSource() method provided by the parent class is final and cannot be overridden into the dataSource. } public Department get(Integer id){ String sql = "SELECT id, dept_name name FROM departments WHERE id = ?" ; RowMapper
      
        rowMapper = new BeanPropertyRowMapper<>(Department.class); return getJdbcTemplate().queryForObject(sql, rowMapper, id); }}
      
Copy the code

Declarative transactions

7.1 Transaction Overview

1. In the application field of JavaEE enterprise development, in order to ensure the integrity and consistency of data, the concept of database transaction must be introduced, so transaction management is an essential technology in enterprise application development.

2. A transaction is a set of database operations that are logically closely related and combined into a single entity (unit of work), all of which are executed or none of which are executed.

3. Four key properties of transactions (ACID)

1) Atomicity: The original meaning of “atom” is “indivisibility”. Atomicity of a transaction refers to the fact that multiple operations involved in a transaction are logically indispensable. The atomicity of a transaction requires that all operations in a transaction either execute or none of them.

2) Consistency: “consistency” refers to data consistency. Specifically, all data is in a consistent state that meets service rules. The consistency principle requires that no matter how many operations are involved in a transaction, the data must be correct before and after the transaction. If one or more operations fail during a transaction, all other operations must be undone to restore the data to the state before the transaction was executed. This is called rollback.

3) Isolation: During the actual operation of the application, transactions are usually executed concurrently, so it is likely that many transactions will process the same data at the same time. Therefore, each transaction should be isolated from other transactions to prevent data corruption. The principle of isolation requires that multiple transactions execute concurrently without interfering with each other.

4) Durability: Durability requires that modifications to data persist permanently after transactions complete, unaffected by system errors or other contingencies. Normally, changes made by transactions to data should be written to persistent storage.

7.2 Spring Transaction Management

7.2.1 Programmatic transaction management

Use the native JDBC API for transaction management

1) Obtain the database Connection object

2) Cancel the automatic commit of transactions

3) Perform the operation

4) Manually commit the transaction when the operation completes normally

5) Rollback transaction on execution failure

6) Close related resources

2, evaluation

Using the native JDBC API to implement transaction management is the cornerstone of all transaction management approaches and is the most typical of programmatic transaction management. Programmatic transaction management requires that transaction management code be embedded in business methods to control the commit and rollback of transactions. When transactions are managed programmatically, additional transaction management code must be included in each transaction operation. Compared with core business, transaction management code is obviously non-core business. If multiple modules use the same pattern of code for transaction management, it will obviously cause a large degree of code redundancy.

7.2.2 Declarative transaction management

Declarative transactions are in most cases better than programmatic transaction management: it separates transaction management code from business methods and implements transaction management declaratively. The fixed pattern of transaction management code, as a crosscutting concern, can be modularized through an AOP approach to declarative transaction management with the help of the Spring AOP framework.

Spring defines an abstraction layer on top of the different transaction management apis, which can be configured to enable application developers to use Spring’s transaction management mechanism without having to understand the underlying implementation details of the transaction management API.

Spring supports both programmatic and declarative transaction management.

7.2.3 Transaction manager provided by Spring

Spring abstracts a whole set of transaction management mechanisms from different transaction management apis, making transaction management code independent of a particular transaction technology. The developer does transaction management by configuration without having to understand how it is implemented at the bottom.

The core of the Spring transaction management abstract is PlatformTransactionManager. It encapsulates a set of technology-independent methods for transaction management. Regardless of which of Spring’s transaction management strategies (programmatic or declarative) are used, a transaction manager is required.

The transaction manager can be declared in the Spring IOC container as a plain bean.

7.2.4 Main implementation of transaction manager

1, DataSourceTransactionManager: in the application needs to handle only one data source, and through JDBC access.

2. JtaTransactionManager: Use JTA(Java Transaction API) for Transaction management on JavaEE application server

3, HibernateTransactionManager: use Hibernate framework to access the database

7.3 Preparing Test Data

7.3.1 demand

7.3.2 Database Tables

CREATE TABLE book (    isbn VARCHAR (50) PRIMARY KEY,    book_name VARCHAR (100),    price INT);CREATE TABLE book_stock (    isbn VARCHAR (50) PRIMARY KEY,    stock INT.CHECK (stock > 0));CREATE TABLE account (    username VARCHAR (50) PRIMARY KEY,    balance INT.CHECK (balance > 0));INSERT INTO account (`username`,`balance`) VALUES ('Tom'.100000);INSERT INTO account (`username`,`balance`) VALUES ('Jerry'.150000);INSERT INTO book (`isbn`,`book_name`,`price`) VALUES ('ISBN-001'.'book01'.100);INSERT INTO book (`isbn`,`book_name`,`price`) VALUES ('ISBN-002'.'book02'.200);INSERT INTO book (`isbn`,`book_name`,`price`) VALUES ('ISBN-003'.'book03'.300);INSERT INTO book (`isbn`,`book_name`,`price`) VALUES ('ISBN-004'.'book04'.400);INSERT INTO book (`isbn`,`book_name`,`price`) VALUES ('ISBN-005'.'book05'.500);INSERT INTO book_stock (`isbn`,`stock`) VALUES ('ISBN-001'.1000);INSERT INTO book_stock (`isbn`,`stock`) VALUES ('ISBN-002'.2000);INSERT INTO book_stock (`isbn`,`stock`) VALUES ('ISBN-003'.3000);INSERT INTO book_stock (`isbn`,`stock`) VALUES ('ISBN-004'.4000);INSERT INTO book_stock (`isbn`,`stock`) VALUES ('ISBN-005'.5000);
Copy the code

7.4 Preliminary Implementation

7.4.1 Configuration Files

<! -- Configure transaction manager --><bean id="transactionManager"       class="org.springframework.jdbc.datasource.DataSourceTransactionManager">    <property name="dataSource" ref="dataSource"/>	  </bean><! -- Enable transaction annotations --><tx:annotation-driven transaction-manager="transactionManager"/>
Copy the code

7.4.2 Annotate the methods requiring transaction control

​ @Transactional

7.5 Propagation behavior of transactions

7.5.1 profile

When a transaction method is called by another transaction method, you must specify how the transaction should propagate. For example, a method may continue to run in an existing transaction, or it may start a new transaction and run in its own transaction. The propagation behavior of a transaction can be specified by propagation properties. Spring defines seven types of propagation behavior.

The Transactional propagation property can be defined in the Propagation property of the @Transactional annotation.

7.5.2 test

7.5.3 instructions

1. Communication behavior REQUIRED

When the bookService’s purchase() method is called by another transaction method, checkout(), it runs by default within an existing transaction. The default propagation behavior is REQUIRED. So there is only one transaction within the start and end boundaries of the checkout() method. This transaction is committed only when the checkout() method ends, leaving the user with no book to buy.

REQUIRES_NEW propagation behavior

Indicates that the method must start a new transaction and run within its own transaction. If a transaction is running, it should be suspended first.

7.5.4 supplement

In Spring 2.x transaction notification, you can set the propagation transaction attribute in the <tx:method> element as follows.

7.6 Isolation level of transactions

7.6.1 Database transaction concurrency Problem

Suppose you now have two transactions: Transaction01 and Transaction02 executing concurrently.

1, dirty reads

[1] Transaction01 Changes the AGE value of a record from 20 to 30.

[2] Transaction02 read Transaction01 updated value: 30.

[3] Transaction01 rollback, AGE value restored to 20.

[4] Transaction02 reads 30 as an invalid value.

2. Do not read repeatedly

[1] Transaction01 read AGE 20.

[2] Transaction02 change AGE to 30.

[3] Transaction01: AGE = 30

3, phantom read

[1] Transaction01 reads part of the STUDENT table.

[2] Transaction02 inserts a new row into the STUDENT table.

[3] Transaction01 read STUDENT table with some extra rows.

7.6.2 Isolation Level

The database system must have the ability to isolate the individual transactions running concurrently so that they do not interfere with each other and avoid various concurrency problems. The degree to which a transaction is isolated from other transactions is called the isolation level. The SQL standard defines multiple transaction isolation levels, which correspond to different interference levels. The higher the isolation level, the better the data consistency, but the weaker the concurrency.

1, READ UNCOMMITTED: READ UNCOMMITTED

Allow Transaction01 to read uncommitted changes in Transaction02.

2, READ COMMITTED

Requires Transaction01 to read only changes that Transaction02 has committed.

REPEATABLE READ 3. REPEATABLE READ

Ensure that Transaction01 can read the same value from a field multiple times, that is, prohibit other transactions from updating the field while Transaction01 is executing.

4. Serialization: SERIALIZABLE

Ensure that Transaction01 can read the same row from a table multiple times, and prohibit other transactions from adding, updating, or deleting the table while Transaction01 is executing. Can avoid any concurrency problems, but performance is very poor.

5. The ability of each isolation level to solve concurrency problems is shown in the table below

Dirty read Unrepeatable read Phantom read
READ UNCOMMITTED There are There are There are
READ COMMITTED There is no There are There are
REPEATABLE READ There is no There is no There are
SERIALIZABLE There is no There is no There is no

The level of support for transaction isolation levels by various database products

Oracle MySQL
READ UNCOMMITTED x Square root
READ COMMITTED Square root Square root
REPEATABLE READ x Square root (the default)
SERIALIZABLE Square root Square root

7.6.3 Specifying the transaction isolation level in Spring

1, annotations,

When you use the @Transactional annotation to declaratively manage transactions, you can set the isolation level in the isolation attribute of @Transactional

2, the XML

In Spring 2.x transaction notifications, you can specify the isolation level in the TX: Method element

7.7 Exception that Triggers transaction Rollback

7.7.1 Default

It is rolled back when a RuntimeException or Error is caught, but not when a compile-time exception is caught.

7.7.2 Setting a Route

1, annotations,

@ Transactional annotation

1) rollbackFor property: Specifies the type of exception that must be rolled back when encountered

2) noRollbackFor attribute: specifies the type of exception that will not be rolled back when encountered

2, the XML

In Spring 2.x transaction notifications, you can specify rollback rules in the <tx:method> element. If there is more than one exception, separate it with a comma.

7.8 Timeout and read-only properties of a transaction

7.8.1 profile

Because transactions can acquire locks on rows and tables, long transactions consume resources and have an impact on overall performance. If a transaction only reads data but does not modify it, the database engine can optimize the transaction.

Timeout transaction attribute: How long a transaction can remain in place before forced rollback. This prevents long running transactions from hogging resources.

Read-only transaction property: Indicates that the transaction reads data but does not update data, which helps the database engine optimize the transaction.

7.8.2 set

1, annotations,

@ Transaction annotations

2, the XML

In Spring 2.x transaction notifications, timeout and read-only attributes can be specified in the <tx:method> element

7.9 Declarative transaction configuration based on XML documents

<! -- Configure transaction facets --><aop:config>    <aop:pointcut expression="execution(* com.atguigu.tx.component.service.BookShopServiceImpl.purchase(..) )" id="txPointCut"/>    <! Associate pointcut expressions with transaction property configurations    <aop:advisor advice-ref="myTx" pointcut-ref="txPointCut"/></aop:config><! Configure xmL-based declarative transactions --><tx:advice id="myTx" transaction-manager="transactionManager">    <tx:attributes>        <! Set transaction properties for a specific method -->        <tx:method name="find*" read-only="true"/>        <tx:method name="get*" read-only="true"/>        <tx:method name="purchase"                    isolation="READ_COMMITTED"                    no-rollback-for="java.lang.ArithmeticException,java.lang.NullPointerException"                   propagation="REQUIRES_NEW"                   read-only="false"                   timeout="10"/>    </tx:attributes></tx:advice>
Copy the code