One, the introduction

1.1 What are the problems in native Web development

Traditional Web development suffers from excessive program consumption due to hard coding (for example, as Dao objects in services as attributes).

Some Java EE apis are complex and inefficient to use (for example, JDBC development steps).

Highly intrusive, poor portability (for example: DAO implementation change, from Connection to sqlSession).

The Spring Framework

2.1 concept

  • Spring is a project management framework as well as a Java EE solution.
  • Spring is a combination of many good design patterns (factory, singleton, proxy, adapter, wrapper, observer, template, policy).
  • Rather than replacing existing framework products, Spring is an organic integration of many frameworks to simplify enterprise development, commonly known as “glue framework.”

2.2 Access and API documentation

Liverpoolfc.tv: spring. IO /

IO /spring-fram…

Three, the Spring architecture composition

The Spring architecture consists of a number of modules, which can be classified as

  • Core technologies:Dependency injection, events, resources, I18N, validation, Data binding, type conversion, SpEL,AOP
  • Testing: Mock objects, TestContext framework, Spring MVC tests, WebTestClient
  • Data access:The transaction, DAO support, JDBC, ORM, marshaling XML
  • Spring MVC and Spring WebFlux Web Framework
  • Integration: remote processing, JMS, JCA, JMX, email, tasks, scheduling, caching.
  • Languages: Kotlin, Groovy, dynamic languages.
Spring Architecture Components
Groupld Artifactid instructions
org-springframework spring-beans Beans support, including Groovy
org-springframework spring-aop Proxy-based AOP support
org.springframework spring-aspects Aspectj-based facets
org.springframework spring-context Application context runtime, including scheduling and remote abstractions
org-springframework spring-context-support Support for integrating common third-party class libraries into the Spring application context
org.springframework spring-core Core modules that other modules depend on
org-springframework spring-expression Spring expression language,SpEL
org.springframework spring-instrument Jvm-guided instrumentation (monitor) agents
org.springframework spring-instrument-tomcat Tomcat’s meter (monitor) agent
org-springframework spring-jdbc Support includes data source Settings and JDBC access support
org.springframework spring-jms Support for helper classes that include sending/receiving JMS messages
org-springframework spring-messaging Support for message architectures and protocols
org.springframework spring-om Object/relational mapping, including support for JPA and Hibernate
org.springframework spring oxm Object/XML Mapping (Object/XML Mapping, OXM)
org.springframework spring-test Unit testing and integration testing support components
org.springframework spring-tx Transaction infrastructure components, including DAO support and JCA integration
org-springframework spring-web Web support package, including client and Web remote calls
org.springframework spring-webmvc REST Web services and MVC implementation of Web applications
org.springframework spring-webmvc-portlet MVC implementation for the Portlet environment
org.springframework spring-websocket WebSocket and SockJS implementations, including STOMP support
org.springframework spring-jcl Jakarta Commons Logging

4. Spring environment construction

4.1 Importing Dependencies

<! -- Spring common dependencies -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.1.6. RELEASE</version>
</dependency>
Copy the code

4.2 Creating a Spring Configuration File

XML, applicationContext. XML, beans.xml


      
<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">
</beans>
Copy the code

5. Spring Factory Code

Define the target Bean type

public interface UserDAO {
    public void deleteUser(Integer id);
}

public class UserDAOImpl implements UserDAO{
    @Override
    public void deleteUser(Integer id) {
        System.out.println("delete User in DAO"); }}Copy the code


in spring-context.xml internally configure the bean tag

<bean id="userDAO" class="com.techoc.dao.UserDAOImpl"></bean>
Copy the code

Calling the Spring Factory API (ApplicationContext interface)

    @Test
    public void testSpringFactory(a){
        // Start the factory
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("/spring-context.xml");
        // Get the object
        UserDAO userDAO = (UserDAO)context.getBean("userDAO");
        userDAO.deleteUser(1);
// context.close();
    }
Copy the code

Dependency and configuration file details

6.1 Spring Dependencies

The Spring framework consists of several modules, each with its own function, that can be used to implement the related dependent Jar packages as required.

  • Note: Jar packages depend on each other, and Maven automatically introduces the dependent Jars into the project by simply importing the outermost JARS.

6.2 schema

The top-level tags in the configuration file contain information about semantic tags

  • XMLNS: Namespace for semantic tags.
  • The XMLNS: XSI :XMLSchema-instance label complies with the Schema label standard.
  • Xsi :schemaLocation: XSD file location, used to describe label semantics, attributes, and value range.

7. IoC (Inversion of Control)

Inverse Of Controll

The way to satisfy the dependency relationship is reversed, which is changed from creating dependent objects by ourselves to pushing them by factories. (Change from active to passive, i.e., reverse)

The strong convergence between components with dependencies is solved, which makes the project form more robust

7.1 Strong coupling in the project

public class UserServiceImpl implements UserService{

    // The strong coupling of UserDAOImpl makes the UserServiceImpl unstable
    private UserDAO userDAO = new UserDAOImpl();
    @Override
    public void deleteUser(Integer id) {
        System.out.println("delete User in Service");
        userDAO.deleteUser(id);
    }
Copy the code

7.2 Solution

// Do not reference any specific component (implementation class), reserve value entry (set/get) where other components are needed
public class UserServiceImpl implements UserService{

    // Meet the dependency strong coupling
    private UserDAO userDAO;
    @Override
    public void deleteUser(Integer id) {
        System.out.println("delete User in Service");
        userDAO.deleteUser(id);
    }

    public UserDAO getUserDAO(a) {
        return userDAO;
    }

    public void setUserDAO(UserDAO userDAO) {
        this.userDAO = userDAO; }}Copy the code
<bean id="userDAO" class="com.techoc.dao.UserDAOImpl"></bean>
<bean id="userService" class="com.techoc.service.UserServiceImpl">
    <! -- Assign the userDAO attribute to a bean with id useDAO
            <property name="userDAO" ref="userDAO"/>
</bean>
Copy the code

At this point, if another UserDAO implementation class needs to be replaced, UserServicelmpl does not need to be changed!

The UserServicelmpl component becomes more robust!

DI (Dependency Injection)

8.1 concept

When Spring creates an object, it assigns values to its properties, which is called dependency injection.

8.2 Set injection

When you create an object, the Spring factory assigns values to the properties of the object through the Set method.

8.2.1 Defining the target Bean type

public class User {
    private Integer id;
    private String password;
    private String sex;
    private Integer age;
    private Date bornDate;
    private String[] hobbys;
    private Set<String> phones;
    private List<String> names;
    private Map<String,String> countries;
    private Properties files;
    //get and set
}
Copy the code

8.2.2 Basic Type + String Type + date type

<bean id="user" class="com.techoc.entity.User">

    <! -- simple: jdk8 basic data types
    <property name="id" value="10"/>
    <property name="password" value="123abc"/>
    <property name="sex" value="male"/>
    <property name="age" value="19"/>
    <property name="bornDate" value="2020/12/12 12:20:30"/>
</bean>
Copy the code

8.2.3 Container Types

<bean id="user" class="com.techoc.entity.User">
    
    <! -- List -->
    <property name="names">
        <list>
            <value>tom</value>
            <value>jack</value>
        </list>
    </property>
    
    <! -- set -->
    <property name="phones">
        <set>
            <value>131111111</value>
            <value>131222222</value>
        </set>
    </property>
    
    <! -- map -->
    <property name="countries">
        <map>
            <entry key="zh" value="china"></entry>
            <entry key="en" value="english"></entry>
        </map>
    </property>
    
    <! -- Properties -->
    <property name="files">
        <props>
            <prop key="url">jdbc:mysql:xxx</prop>
            <prop key="username">root</prop>
        </props>
    </property>
</bean>
Copy the code

8.2.4 Self-built Type

<! Secondary beans are treated as properties -->
<bean id="addr" class="com.techoc.entity.Address">
    <property name="id" value="1"/>
    <property name="city" value="Beijing"/>
</bean>

<bean id="user" class="com.techoc.entity.User">
    <! -- Custom type -->
    <property name="address" ref="addr"/>
</bean>
Copy the code

8.3 Structural injection

When an object is created, the Spring factory assigns values to its properties via constructors.

8.3.1 Defining the target Bean type

public class User {
    private Integer id;
    private String password;
    private String sex;
    private Integer age;
    
    // constructor
    public User(Integer id, String password, String sex, Integer age) {
        this.id = id;
        this.password = password;
        this.sex = sex;
        this.age = age; }}Copy the code

8.3.2 injection

<! -->
<bean id="student" class="com.techoc.entity.Student">
    <constructor-arg name="id" value="1"/>
    <constructor-arg name="name" value="shine"/>
    <constructor-arg name="sex" value="male"/>
    <constructor-arg name="age" value="19"/>
</bean>
Copy the code

8.4 Automatic Injection

You don’t have to specify which attribute to assign or what to assign in the configuration.

Spring automatically looks up a bean in the factory and injects property values into properties based on some “principle.

<bean id="userDAO" class="com.techoc.dao.UserDAOImpl"/>
<! -- Type-based injection -->
<bean id="userService" class="com.techoc.service.UserServiceImpl" autowire="byType">
</bean>
Copy the code
<bean id="userDAO" class="com.techoc.dao.UserDAOImpl"/>
<! -- name based injection -->
<bean id="userService" class="com.techoc.service.UserServiceImpl" autowire="byName">
</bean>
Copy the code

9. Some details about beans

9.1 Control the singleton and multi-instance modes of simple objects

Configure the < bean scope = “singleton | prototype” / >

  • Singleton (default) : Every time you call the factory, you get the same object
  • Prototype: Every time a factory is called, a new object is created
<! -- Singleton (default) : Every time you call the factory, you get the same object. Prototype: Every time a factory is called, a new object is created. -->
<bean id="userService" class="com.techoc.service.UserServiceImpl" autowire="byType" scope="prototype">
Copy the code
  • Note: Depending on the scenario, you need to determine the singleton and multi-instance patterns of the object
  • Can be shared: Service, DAO, SqlSessionFactory(or all factories)
  • Cannot be shared: Connection, SqlSession, ShoppingCart

9.2 FactoryBean creates complex objects

What it does: Allows Spring to create complex objects, or objects that cannot be created directly through reflection.

9.2.1 Implement the FactoryBean interface

  • Note: The isSingleton method returns true/false depending on the nature of the object being created.
  • For example: Connection should not be shared by multiple users, return false.
  • For example: SqlSessionFactory heavy resource, should not create too many, return true.

9.2.2 configuration Spring – Context. The XML

9.2.3 special case

Spring Factory features

10.1 Han-style to create advantages

After the factory is created, all objects in the Spring configuration file are created (Hungry style).

Improve program efficiency. Avoid multiple 10s to reduce object creation time. (The concept is similar to connection pool, created once, accessed directly when used)

10.2 Life cycle approach

  • Custom initialization method: Add the “init-method” property and Spring will call this method after the object is created.

  • Custom destroy methods: Add the “destroy-method” property, and Spring will call this method before destroying the object.

  • Destroy: After the factory’s close() method is called, Spring destroys all created singletons.

  • Classification: Singleton objects destroyed by the Spring container, Prototype objects destroyed by the JVM.

10.3 Life cycle Notes

Initialize and destroy annotations

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

public class Test {

    / / initialization
    @PostConstruct
    public void init(a) {
        System.out.println("init method executed");
    }

    / / destroy
    @PreDestroy
    public void destroy(a) {
        System.out.println("destroy method executed"); }}Copy the code

10.4 Life cycle stages

Singleton bean: the singleton

Create with factory start → Constructor → Set method (inject value) →init(initialize) → build complete → Destroy with factory close

Prototype created → constructor → Set method (injected value) →init(initialized) → build complete →JVM garbage collection destroyed

11. Agent design pattern

11.1 concept

Separating core functions from auxiliary functions (transaction, log, performance monitoring code) makes core business functions purer and auxiliary business functions reusable.

11.2 Static Proxy Design Mode

Through the object of the proxy class, adding auxiliary functions for the object of the original class (object of the target class), it is easier to change the proxy implementation class and facilitate maintenance.

  • Proxy class = implements the same interface as the original class + adds accessibility + calls the business methods of the original class.
  • Static proxy problems
    • There are too many proxy classes, which is not good for project management.
    • Multiple proxy class auxiliary function code hole, modify, poor maintenance.

11.3 Dynamic Proxy Design Mode

Dynamically create objects of the proxy class, adding helper functions to objects of the original class.

11.3.1 JDK Dynamic Proxy Implementation (interface-based)

public class DynamicProxyTest {

    @Test
    public void testJDK(a) {

        / / target
        FangDongService fangDongService = new FangDongServiceImpl();

        // Additional functionality based on the interface
        InvocationHandler ih = new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                // Auxiliary functions, additional functions
                System.out.println("Release rental information 1");
                System.out.println("Show Tenant 1");
                / / core
                fangDongService.zufang();
                return null; }};// Dynamically generate proxy classesFangDongService proxy = (FangDongService) Proxy.newProxyInstance( DynamicProxyTest.class.getClassLoader(), fangDongService.getClass().getInterfaces(), ih ); proxy.zufang(); }}Copy the code

11.3.2 CGlib Dynamic Proxy Implementation (Based on inheritance)

public class DynamicProxyTest {

    @Test
    public void testCGLIB(a) {
        / / target
        FangDongService fangDongService = new FangDongServiceImpl();

        //
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(FangDongServiceImpl.class);
        enhancer.setCallback(new org.springframework.cglib.proxy.InvocationHandler() {
            @Override
            public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
                // Auxiliary functions, additional functions
                System.out.println("Release rental Information 2");
                System.out.println("Show Tenant 2");
                / / core
                fangDongService.zufang();
                return null; }});// Dynamically generate proxy classesFangDongServiceImpl proxy = (FangDongServiceImpl) enhancer.create(); proxy.zufang(); }}Copy the code

12. AOP Faceted Programming

12.1 concept

AOP (Aspect Oriented Programming), or section-oriented Programming, utilizes a technique called crosscutting,

Slice open the inside of the encapsulated object and encapsulate the common behavior that affects multiple classes into a reusable module named “Aspect, “or section.

“Facets” are simply those that are irrelevant to the business, but are encapsulated by logic or responsibilities that business modules invoke together.

It is convenient to reduce the duplicate code of the system, reduce the coupling degree between modules, and is conducive to future operability and maintainability.

12.2 AOP development terminology

  • Join Points: Join points are methods that exist objectively in application classes and can be intercepted by Spring to cut into content.
  • Pointcut: Join points cut into by Spring.
  • Advice: Additional capabilities can be added to pointcuts: pre-notification, post-notification, exception notification, surround notification, and so on.
  • Target: The Target object of the agent
  • A special enhancement that dynamically adds fields and methods to classes at run time.
  • Weaving: The process of applying notifications to specific classes to create new proxy classes.
  • Proxy: The resulting class that is woven into the advice by AOP.
  • Aspect: Consists of pointcuts and notifications that weave crosscutting logic into the join points specified by the Aspect.

12.3 role

Spring’s AOP programming is all about adding helper functionality to the methods of the original class through dynamic proxy classes.

12.4 Environment Construction

Import dependence

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>5.1.6. RELEASE</version>
</dependency>
Copy the code

12.5 Development Process

Defining primitive classes

public interface UserService {
    public void save(a);
}
Copy the code
public class UserServiceImpl implements UserService {
    public void save(a){
        System.out.println("save method executed"); }}Copy the code

Define notification classes (add extra functionality)

//method: the method of the target object to execute
/ / the args: parameters
/ / target: the target
public class MyAdvice implements MethodBeforeAdvice{// Implement the pre-notification interface
	public void before(Method method, Object[] args, Object target) throws Throwable {
		System.out.println("before advice executed..."); }}Copy the code

Defining Bean labels

<! -- Original object -->
<bean id="us" class="com.techoc.aop.UserServiceImpl"/>

<! -- Auxiliary object -->
<bean id="myAdvice" class="com.techoc.aop.MyAdvice"/>
Copy the code

Defining pointcuts

Form an Aspect

<aop:config>
    <! - point expression: expression of execution (to perform the position of the * (modifier) * (return) * (name of the class) * (method) * (parameters)) -- -- >
    <aop:pointcut id="myPointCut" expression="execution(* save())" />
</aop:config>
Copy the code
<aop:config>
    <! -- Assembly section -->
    <aop:advisor advice-ref="myAdvice" pointcut-ref="myPointCut" />
</aop:config>
Copy the code

12.6 AOP summary

  • Through the coding process provided by AOP, it is more convenient to customize the aspects and more convenient to customize the dynamic proxy.
  • Then it solves the problem of auxiliary functions completely.
  • The single responsibility in business class is better guaranteed;
  • Accessibility is also very reusable.

12.7 notify the class

Define notification class to achieve notification effect

Before notification: MethodBeforeAdvice AfterAdvice AfterAdvice AfterReturningAdvice// If there is an exception, the method will end with no return valueException notification: ThrowsAdvice Surround notification: MethodInterceptorCopy the code

12.8 Wildcard Entry Point

Wildcard pointcuts based on expressions

<! -- Match parameters -->
<aop:pointcut id="myPointCut" expression="execution(* *(com.techoc.entity.User))"/>
<! -- Match method name (no arguments) -->
<aop:pointcut id="myPointCut" expression="execution(* save())"/>
<! -- Match method name (any parameter) -->
<aop:pointcut id="myPointCut" expression="execution(* save(..) )"/>
<! Match the return value type -->< aop:pointcut id = "myPointCut" expression="execution(com.techoc.entity.User *(..) ) "/ ><! -- Match class name -->< aop:pointcut id = "myPointCut" expression="execution(* com.techoc.service.UserServiceImpl.*(..) ) "/ ><! -- Match package name -->
<aop:pointcut id="myPointCut" expression="execution(* com.techoc.service.*.*(..) )" />
<! Match package name and subpackage name -->
<aop:pointcut id="myPointCut" expression="execution(* com.techoc.. *. * (..) )" />
Copy the code

12.9 JDK and CGLIB selection

  • Spring base includes JDK proxy and Cglib proxy

  • The basic rule is: the target business class uses a JDK proxy if it has an interface, and a CGLib proxy if it does not

12.10 Post-Processor

  • Many post-processors are defined in Spring;
  • Before each bean is created, there will bea post-processing process, namely reprocessing, to make relevant changes and adjustments to the bean;
  • In Spring-AOP, there is a specialized post-processor that is responsible for reprocessing a proxy component from the original business component (Service).

12.10.1 Post-Processor Definition

/** * After the bean is created, it reprocesses the bean */
public class MyBeanPostProcessor implements BeanPostProcessor {
    /** * is executed before the bean's init method@paramBean The original bean object *@param beanName
    *@return
    *@throws BeansException
    */
    public object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException{
        System.out.println("Post-processor executes before init"+bean.getClass());
        return bean;
    }
    /** * executes after the bean's init method@paramThe bean bean postProcessBeforeInitialization back *@param beanName
    *@return
    *@throws BeansException
    */@ 0verride
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("Post-processor executes after init ~~~"+bean.getClass());
        return bean;// The return here is the final return value of getBean()}}Copy the code

12.10.2 Configuring a Post-PROCESSOR

<1-- Configure the post-processor to intervene in all bean declaration cycles in the factory --><bean class="com.techoc.beanpostprocessor.MyBeanPostProcessor"></bean>
Copy the code

12.10.3 Bean life cycle

Structure – > injection properties Meet depend on the processor front process after > — – > processor rear process after initialization — — > > return — – > destroyed

Spring+MyBatis

13.1 Configuring a Data Source

Configure the data source into the project

13.1.1 introducedjdbc.propertiesThe configuration file

jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mydb? useUnicode=true&characterEncoding=UTF-8
jdbc.username=root
jdbc.password=123456
jdbc.init=1
jdbc.minIdle=1
jdbc.maxActive=3
Copy the code

13.1.2 Integrate the Spring profile with the Properties profile

<! -- Configuration file parameterization (parameter placeholder) -->
<context:property-placeholder location=" classpath:jdbc.properties"/>

<! -- Integrate with PooledDataSource -->
<bean id="dataSource" class="org.apache.ibatis.datasource.pooled.PooledDataSource">
    <property name="driver"value="${jdbc.driverClass}"/>
    <property name="url" value="${jdbc.url}"/>
    <property name="username" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
</bean>

<! Integration with DruidDataSource (optional) -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
    <! -- Basic configuration -->
    <property name="driverClassName" value="${jdbc.driver}"/>
    <property name="url" value="${jdbc.url}"/>
    <property name="username" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
</bean>
Copy the code

13.1.3 Druid Connection Pool This parameter is optional

<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
    <! -- Basic configuration -->
    <property name="driverClassName" value="${jdbc.driver}"/>
    <property name="url" value="${jdbc.url}"/>
    <property name="username" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>

    <! -- Configure initial size, min, Max -->
    <property name="initialSize" value="${jdbc.init}"/>
    <property name="minIdle" value="${jdbc.minIdle}"/>
    <property name="maxActive" value="${jdbc.maxActive}"/>
    <! -- Set timeout time for waiting to get connections -->
    <property name="maxWait" value="60000"/>
    <! -- How often is it configured to detect idle connections that need to be closed in milliseconds -->
    <property name="timeBetweenEvictionRunsMillis" value="60000"/>
    <! Set the minimum time for a connection to live in the pool, in milliseconds.
    <property name="minEvictableIdleTimeMillis" value="300000"/>
</bean>
Copy the code

13.1.4 Druid Monitoring Center

<! --web.xml-->
<servlet>
    <servlet-name>DruidStatView</servlet-name>
    <servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>DruidStatView</servlet-name>
    <url-pattern>/druid/*</url-pattern>
</servlet-mapping>
Copy the code

13.1.5 Test monitoring center

Configure tomcat and access protocol: / / IP: port/project/druid/index. The HTML

13.2 Mybatis integration Method 1

Configure the SqlSessionFactory, DAO, and Service into the project

13.2.1 Importing dependencies

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>4.3.6. RELEASE</version>
</dependency>

<! Spring + Mybatis integrated dependencies -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>1.3.1</version>
</dependency>
Copy the code

13.2.2 configuration sqlSessionFactory

<! Sq1SessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <! -- Add connection pool -->
    <property name="dataSource" ref="dataSource"/>
    <property name="mapperLocations">
        <list>
            <value>classpath:com/techoc/dao/*.xml</value>
        </list>
    </property>
    <property name="typeAliasesPackage" value="com.techoc.entity"/>
</bean>
Copy the code

13.2.3 configuration MapperScannerConfigurer

Manage the creation of DAO implementation classes and create DAO objects to store in the factory for management

  • Scan all DAO interfaces to build DAO implementations

  • Put the DAO implementation into factory administration

  • The FACTORY ID of the DAO implementation object is: “lowercase – class name of the interface”,

    For example: UserDAO = = > UserDAO, OrderDAO = = OrderDAO

<! -- mapper ScannerConfigurer -->
<bean id="mapperScannerConfigurer9" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <! <property name="basePackage" value="com.a.dao,com.b.dao">/property> -->
    <property name="basePackage" value="com.techoc.dao"/>
    <! This configuration can be omitted if there is only one Sq1SessionFactory bean in the factory.
    <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>
Copy the code

13.2.4 configuration Service

<bean id="userService" class="com.techoc.service.UserServiceImpl">
    <! -- notice that the value in ref is the lowercase interface name corresponding to the DA0 interface -->
    <property name="userDA0"ref="userDA0"/>
</bean>
Copy the code

13.3 MyBatis integration Method 2

13.3.1 Spring takes over Mybatis implementation classes

  • Create UserMapper interface and create usermapper.xml

  • Create the UserMapperImpl implementation class

  • Use the constructor to inject the SqlSessionTemplate in the Spring configuration file

public class UserMapperImpl implements UserMapper {
	// All the previous operations were performed using sqLSession, and now use SqLSessionTemplate after Spring integration
    private SqlSessionTemplate sqlSession;

    public void setSqlSession(SqlSessionTemplate sqlSession) {
        this.sqlSession = sqlSession;
    }

    @Override
    public List<User> selectUser(a) {
        returnsqlSession.getMapper(UserMapper.class).selectUser(); }}Copy the code
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
    <! Constructor injection -->
    <constructor-arg index="0" ref="sqlSessionFactory"/>
</bean>

<bean id="userMapper" class="com.techoc.mapper.UserMapperImpl">
    <property name="sqlSession" ref="sqlSession"/>
</bean>
Copy the code

The test method

@Test
public void test1(a){
    ApplicationContext context = new ClassPathXmlApplicationContext("spring-dao.xml");

    UserMapper userMapper = context.getBean("userMapper", UserMapper.class);

    List<User> users = userMapper.selectUser();

    for(User user : users) { System.out.println(user); }}Copy the code

13.4 Integrating MyBatis Method 3

13.4.1 inheritanceSqlSessionDaoSupport

  • createUserMapperInterface, createUserMapper.xml
  • createUserMapperImplThe implementation class
  • UserMapperImplThe following
public class UserMapperImpl extends SqlSessionDaoSupport implements UserMapper {
    @Override
    public List<User> selectUser(a) {
        returngetSqlSession().getMapper(UserMapper.class).selectUser(); }}Copy the code

When the implementation class inherits SqlSessionDaoSupport, there is no need to inject the SqlSessionTemplate into the Spring configuration file

<bean id="userMapper2" class="com.techoc.mapper.UserMapperImpl">
    <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
Copy the code

The test method

@Test
public void test2(a){
    ApplicationContext context = new ClassPathXmlApplicationContext("spring-dao.xml");

    UserMapper userMapper = context.getBean("userMapper", UserMapper.class);

    List<User> users = userMapper.selectUser();

    for(User user : users) { System.out.println(user); }}Copy the code

13.5 Integrating MyBatis Method 4

13.5.1 Let Spring create implementation classes

<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
    <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
    <property name="mapperInterface" value="com.techoc.mapper.UserMapper"/>
</bean>
Copy the code

The test method

@Test
public void test(a) {
    ApplicationContext context = new ClassPathXmlApplicationContext("spring-dao.xml");

    UserMapper userMapper = context.getBean("userMapper", UserMapper.class);
    List<User> users = userMapper.selectUser();

    for(User user : users) { System.out.println(user); }}Copy the code

Xiv. Business [Key Points]

14.1 configuration DataSourceTransactionManager

Transaction manager, which holds DataSource and controls transaction functionality (COMMIT, ROLLBACK, etc.)

<! --1. Introduce a transaction manager that relies on the DataSource to get connections and control the transaction logic.
<bean id="tx" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
</bean>
Copy the code

Note: DataSourceTransactionManager and SqlSessionFactoryBean to inject the same DataSource Bean, otherwise the transaction control failure

14.2 Configuring transaction Notification

Based on the transaction manager, further customization generates an additional feature: Advice.

This Advice can cut into any method that requires a transaction, controlling the transaction for the method through the transaction manager.

<tx:advice id="txManager" transaction-manager="tx">
    <! Define transaction attributes -->
    <tx:attributes>
        <! --propagation="REQUIRED" read-only="false"/>-->
        <tx:method name="queryUser" isolation="DEFAULT" propagation="SUPPORTS" read-only="true" timeout="1"
                   rollback-for="Exception"/>
        <! -- methods that end with User, when entered into this method, use the corresponding transaction implementation -->
        <tx:method name="*User" isolation="DEFAULT" propagation="REQUIRED" read-only="false" timeout="1"
                   rollback-for="Exception"/>
        <! -- All remaining methods -->
        <tx:method name="*"/>
    </tx:attributes>
</tx:advice>
Copy the code

14.3 Transaction Properties

14.3.1 Isolation Level

14.3.1.1 concept

Isolation Isolation level

The name of the describe
default (Default) (Use the default database Settings) (Recommended)
read-uncommited Read uncommitted
read-commited Read commit (default Isolation level for Oracle database)
repeatable-read Repeatable reads (default isolation level for MySQL database)
serialized-read Serialization to read

The isolation level from low to high is read-uncommited<read-commited<repeatable-read<serialized-read

14.3.1.2 features
  • Security: The higher the level, the more secure it is when multiple transactions are concurrent. Because less data is shared, transactions interfere with each other less.

  • Concurrency: The higher the level, the worse the concurrency for multiple transactions. As less data is shared, inter-transaction blocking increases.

14.3.1.3 Concurrency Problems

Security issues when transactions are concurrent

The problem describe
Dirty read A transaction reads data that another transaction has not yet committed. The value is greater than or equal to read-commited
Unrepeatable read Multiple reads of the same row within a transaction may produce inconsistent results. Greater than or equal to repeatable -read prevents
The phantom read If a transaction reads the same contents of a table more than once, the result does not change. Serialized – read can be prevented

14.3.2 Communication Behavior

Propagation behavior

When it comes to transaction nesting (Service calling Service), you can set:

  • SUPPORTS= New transactions are not started if there are no external transactions. If an external transaction exists, it is merged into the external transaction. (Suitable for enquiry)
  • REQUIRED= Start a new transaction if no external transaction exists; If an external transaction exists, it is merged into the external transaction. (Default value) (Suitable for adding, deleting, and changing)
REQUIRED Supports current transactions and creates a new one if there are none. This is the most common choice.
SUPPORTS Current transactions are supported, and non-transactionally executed if there are none.
MANDATORY Supports current transactions and throws an exception if there are none.
REQUIRES_NEW Create a new transaction and suspend the current transaction if one exists.
NOT_SUPPORTED Performs the operation nontransactionally, suspending the current transaction if one exists.
NEVER Executes nontransactionally, throwing an exception if a transaction currently exists.
NESTED Support for current transactions. If the current transaction exists, a nested transaction is executed, and if none exists, a new transaction is created.

Sexual 14.3.3, speaking, reading and writing

Sexual readonly, speaking, reading and writing

  • True: read-only, which improves query efficiency. (Suitable for enquiry)
  • False: Read and write. (Default value) (Suitable for adding, deleting, and changing)

14.3.4 Transaction Timeout

Timeout Indicates the timeout time of a transaction

The data required by the current transaction is occupied by another transaction and waits.

  • 100: Custom wait time of 100(seconds).
  • -1: the wait time is specified by the database. Default value. (recommended)

14.3.5 Transaction Rollback

Rollback-for Rollback properties

  • If a RuntimeException is thrown in a transaction, it is automatically rolled back
  • If a CheckException(non-runtime Exception) is thrown in a transaction, the transaction is not automatically rolled back, but committed by default
  • Background-for =”Exception”; background-for =”Exception”

14.4 woven

Cut transaction management Advice into the business approach that requires transactions

<aop:config>
    <aop:pointcut id="pc_tx" expression="execution(* com.techoc.service.UserServiceImpl.*(..) )"/>
    <aop:advisor advice-ref="txManager" pointcut-ref="pc_tx"/>
</aop:config>
Copy the code

15. Annotation development

15.1 the statement Bean

A <bean to replace a component of a self-built type… > tag. Beans can be declared faster

  • @service This parameter is reserved for the business class
  • The @Repository DAO implements class specificity
  • @Controller Web layer only
  • @ Component of general
  • The @scope user controls the creation mode of the bean

       
       
      
// @service default beanId== lowercase class name "userServiceImpl"
// @service ("userService")
@Service	// Declare the bean with id="userServiceImpl"
@Scope("singleton")	// Declare creation mode, default is singleton mode; @scope ("prototype") can be set to multi-example mode
public class UserServiceImpl implements UserService {... }Copy the code

15.2 Injection (DI)

Used to complete the injection of property values in the bean

  • @autoWired Automatic injection based on type
  • @resource is automatically injected based on the name
  • The @qualifier (“userDAO”) specifies the ID of the bean to be injected automatically, usually in conjunction with @AutoWired
  • @value Inject simple type data (jdk8 types +String)
@Service
public class UserServiceImpl implements UserService {
    
    @Autowired// Inject a bean of type UserDA0
    @Qualifier("userDA02")// If there are multiple beans of type UserDA0, you can use this annotation to select one of them
    private UserDAO userDAO;
}
Copy the code
@Service
public class UserServiceImpl implements UserService {
    
    @Resource("userDA03")// Inject the bean with id="userDA03"
    private UserDAO userDAO;
    Private UserDAO UserDAO; * /
}
Copy the code
public class XX{
    @Value("100")// Inject numbers
    private Integer id;
    @Value("shine")/ / injection String
    private String name;
}
Copy the code

15.3 Transaction control

Used to control transaction entry

  • @Transactional
// Every method in a class cuts into a transaction (except for methods that have their own transaction control)
@Transactional(isolation=Isolation.READ_COMMITTED,propagation=Propagation.REQUIRED,readonly=false,rollbackFor=Exception. class,timeout=-1)
public class UserServiceImpl implements UserService {
    
    // The method's own transaction control is valid only for this method
    @Transactional(propagation=Propagation.SUPPORTS)
    public List<User> queryA11(a){
        return userDao.queryA11();
    }
    public void save(User user){ userDao.save(user); }}Copy the code

15.4 Comments Required Configurations

<! Tell Spring which packages have annotated classes, methods, and properties.
<context:component-scan base-package = "com.techoc"/>
<! - inform spring, @ Transactional based in custom affairs, txManager = DataSourceTransactionManager - >
<tx:annotation-driven transaction-manager = "txManager"/>
Copy the code

15.5 AOP development

15.5.1 Use of Annotations

@Aspect // Declare that this class is an aspect class: it contains pointcuts and advice.
@Component // Declare the component and enter the factory
public class MyAspect {
    // Define the pointcut
    @Pointcut("execution(* com.techoc.service.UserServiceImpl.*(..) )"
    public void pc(a){}

    @Before("pc()") // Pre-notification
    public void mybefore(JoinPoint a) {
        System.out.println("target:"+a.getTarget());
        System.out.println("args:"+a.getArgs());
        System.out.println("method's name:"+a.getSignature().getName());
        System.out.println("before~~~~");
    }

    @AfterReturning(value="pc()",returning="ret") // post notification
    public void myAfterReturning(JoinPoint a,Object ret){
        System.out.println("after~~~~:"+ret);
    }

    @Around("pc()") // Wrap around the notification
    public Object myInterceptor(ProceedingJoinPoint p) throws Throwable {
        System.out.println("interceptor1~~~~");
        Object ret = p.proceed();
        System.out.println("interceptor2~~~~");
        return ret;
    }
    @AfterThrowing(value="pc()",throwing="ex") // Exception notification
    public void myThrows(JoinPoint jp,Exception ex){
        System.out.println("throws");
        System.out.println("= = = ="+ex.getMessage()); }}Copy the code

15.5.2 configuration

<! Add the following configuration to enable AOP annotations -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
Copy the code

Collect Junit

16.1 Importing Dependencies

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>5.1.6. RELEASE</version>
</dependency>
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
</dependency>
Copy the code

16.2 coding

  • The factory creation process can be eliminated;
  • You can inject the component to be tested directly into the test class.
// Test starts, starts the Spring factory, and the current test class is also produced by the factory
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class TestSpringMybatis {
    @Autowired	// Automatic injection
    @Qualifier("userService2")
    private UserService userService;

    @Autowired
    private SqlSessionFactory sqlSessionFactory;

    @Test
    public void testSpringJunit(a) {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        List<User> users = mapper.queryUsers();
        for(User user : users) { System.out.println(user); }}}Copy the code