Summary of the Spring

What is the Spring

Spring is a lightweight open source framework for layered Java SE/EE applications called Full-Stack.

It provides performance layer SpringMVC and persistence layer Spring JDBC Template as well as business layer transaction management and many other enterprise-level application technologies. It can also integrate many well-known third-party frameworks and class libraries in the open source world, and gradually become the most used Java EE enterprise application open source framework.

Two cores: Inverse Of Control (IOC) and Aspect Oriented Programming (AOP) as the kernel.

Development history of Spring

In 1997, IBM proposed the idea of EJB in 1998, SUN developed the development standard specification EJB1.0 in 1999, EJB1.1 released in 2001, EJB2.0 released in 2003, EJB2.1 released in 2006, Expert One on One J2EE Design and Development (2002) It points out some major flaws in the JavaEE and EJB component frameworks; Propose a simpler solution for ordinary Java class dependency injection. In 2004, he wrote Expert one-to-one J2EE Development without EJB, which explained how to develop JavaEE without using EJB. In April of the same year, Spring 1.0 was born in October 2006. Release Spring2.0 in December 2009, release Spring3.0 in December 2013, release Spring4.0 in September 2017, release the latest general version of Spring5.0 (GA)Copy the code

Spring advantage

Spring is a container that allows all object creation and relationship maintenance to be managed by Spring. The relationship between objects, usually said that when one module (object) changes also need to change other modules (object), this is coupling, excessive coupling will increase the maintenance cost of code. To decouple as far as possible 2) AOP programming support Spring provides section-oriented programming, convenient implementation programs for permission interception, running monitoring and other functions. 3) support for declarative transaction management through configuration, without manual programming 4) convenient testing, reduce the use of JavaEE API Spring Junit4 support, can use annotations testing 5) convenient integration of a variety of excellent frameworks do not rule out a variety of excellent open source frameworks, Direct support for a variety of excellent frameworks is provided internallyCopy the code

Spring Architecture

I met the IOC

An overview of the

Inverse Of Control is not a technology, but a design idea. Its purpose is to guide us to design programs that are more loosely coupled.

Control: In Java, control over objects (creation, destruction) is reversed: Control over objects is shifted from the developer’s manual control of the class to the Spring container

Take a chestnut

* The traditional method requires a userDao instance and requires the developer to manually create the new userDao (); Now we need a userDao instance, obtained directly from Spring's IOC container, with object creation in Spring's handsCopy the code

Custom IOC containers

introduce

  • The requirement implements the decoupling of service layer and DAO layer code

  • Step analysis

    1. Create a Java project to import custom IOC-related coordinates
    2. Write Dao interfaces and implementation classes
    3. Write the Service interface and implementation classes
    4. Write test code

implementation

1) Create a Java project and import custom IOC coordinates

<dependencies>
    <dependency>
        <groupId>dom4j</groupId>
        <artifactId>dom4j</artifactId>
        <version>1.6.1</version>
    </dependency>
    <dependency>
        <groupId>jaxen</groupId>
        <artifactId>jaxen</artifactId>
        <version>1.1.6</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
</dependencies        
Copy the code

2) Write Dao interfaces and implementation classes

public interface UserDao {

    public void save(a);
}
Copy the code
public class UserDaoImpl implements UserDao {

    public void save(a) {
        System.out.println("Saved successfully..."); }}Copy the code

3) Write the Service interface and implementation class

public interface UserService {

    public void save(a);
}
Copy the code
public class UserServiceImpl implements UserService {

    private UserDao userDao;

    public void save(a){
        userDao = newUserDaoImpl(); userDao.save(); }}Copy the code

4) Write test code

public class UserTest {

    @Test
    public void testSave(a) throws Exception {
        UserService userService = newUserServiceImpl(); userService.save(); }}Copy the code

5) problem

The current service object and DAO object are too coupled, and each new object is a new object, resulting in excessive server stress.

The principle of decoupling is that compile-time dependencies do not exist, but run-time dependencies do.

6) Write beans.xml

Define all the information needed to create objects in the configuration file


      
<beans>
    <bean id="userDao" class="com.lagou.dao.impl.UserDaoImpl"></bean>
</beans>
Copy the code

7) Write the BeanFactory utility class

public class BeanFactory {

    private static Map<String, Object> ioc = new HashMap<>();

    // Initializes the object instance when the program starts
    static {
        try {
            // 1. Read the configuration file
            InputStream in = BeanFactory.class.getClassLoader().getResourceAsStream("beans.xml");
            // 2. Parse XML
            SAXReader saxReader = new SAXReader();
            Document document = saxReader.read(in);
            // 3. Write xpath expressions
            String xpath = "//bean";
            // 4. Get all the bean tags
            List<Element> list = document.selectNodes(xpath);
            // 5. Iterate over and create an object instance and set it to the map collection
            for (Element element : list) {
                String id = element.attributeValue("id");
                String className = element.attributeValue("class"); Object object = Class.forName(className).newInstance(); ioc.put(id, object); }}catch(Exception e) { e.printStackTrace(); }}// Get the object instance with the specified id
    public static Object getBean(String beandId) {
        returnioc.get(beandId); }}Copy the code

8) Modify the UserServiceImpl implementation class

public class UserServiceImpl implements UserService {

    private UserDao userDao;

    public void save(a) throws Exception
        userDao = (UserDao) BeanFactory.getBean("userDao"); userDao.save(); }}Copy the code

Knowledge summary

* The upgraded BeanFactory is a simple Spring IOC container. * We need to create a new userDao () by hand; * Now we need a UserDAO instance, obtained directly from Spring's IOC container, with object creation giving Spring control * End goal: code decouplingCopy the code

Spring Quick Start

introduce

  • Requirements: Use Spring’s IOC to decouple the service layer from the DAO layer code

  • Step analysis

1. Create a Java project and import the basic coordinates of Spring development; 2. Write Dao interfaces and implementation classes; 3. Create spring core configuration file 4. Configure UserDaoImpl in spring configuration file 5. Get the Bean instance using the Spring-related APICopy the code

implementation

1) Create a Java project and import the basic spring development coordinates

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.1.5. RELEASE</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
</dependencies>
Copy the code

2) Write Dao interfaces and implementation classes

public interface UserDao {

    public void save(a);
}
Copy the code
public class UserDaoImpl implements UserDao {

    public void save(a) {
        System.out.println("Saved successfully..."); }}Copy the code

3) Create the Spring core configuration file


      
<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

4) Configure UserDaoImpl in the Spring configuration file

<beans>
    <bean id="userDao" class="com.lagou.dao.impl.UserDaoImpl"></bean>
</beans>
Copy the code

5) Get Bean instances using spring related apis

public class UserTest {

    @Test
    public void testSave(a) throws Exception {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserDao userDao = (UserDao) applicationContext.getBean("userDao"); userDao.save(); }}Copy the code

Knowledge summary

Spring development steps

Create the Bean. 3. Create applicationContext.xml. 4. Configure beans in the configuration file. 5. Create the ApplicationContext object and execute getBeanCopy the code

Spring related API

API inheritance system introduction

Spring’s API architecture is extremely large, so let’s focus on just two BeanFactories and ApplicationContext

BeanFactory

The BeanFactory is the core interface of the IOC container, which defines the basic functions of IOC.

Features: The first time the getBean() method is called, an instance of the specified object is created

BeanFactory beanFactory = 
                    new XmlBeanFactory(new
                    ClassPathResource("applicationContext.xml"));
Copy the code

ApplicationContext

Representing the application context object, you can obtain the Bean object of the IOC container in Spring.

Features: When the Spring container starts, instances of all objects are loaded and created

Common implementation classes

1. The ClassPathXmlApplicationContext it from class loading under the root of the configuration file It is recommended to use this. 2. FileSystemXmlApplicationContext it loaded from disk path configuration files, configuration files can be anywhere in the disk. 3. AnnotationConfigApplicationContext when using annotations configuration container object, you need to use these to create the spring container. It is used to read annotations.Copy the code
ApplicationContext app =
                        new
ClassPathXmlApplicationContext("applicationContext.xml");
Copy the code

Commonly used method

1. Object getBean(String name); Get the Bean instance from the container based on the Bean ID, return Object, need to strong.2. <T> T getBean(Class<T> requiredType); Matches Bean instances from the container by type. This method reports an error when there are more than one Bean of the same type in the container.3. <T> T getBean(String name,Class<T> requiredType); Get the Bean instance based on the Bean ID and type, solving the problem of having more than one Bean of the same type in the container.Copy the code

Knowledge summary

ApplicationContext app = new ClasspathXmlApplicationContext("The XML file");
    app.getBean("id");
    app.getBean(Class);
Copy the code

Spring configuration file

Bean label basic configuration

<bean id="" class=""></bean>* For configuration objects to be created by Spring. Class: the fully qualified name of the Bean * By default it calls the class's no-argument constructor, and cannot be created without it.Copy the code

Bean label scope configuration

<bean id="" class="" scope=""></bean>
Copy the code

The scope attribute indicates the scope of the object. Its values are as follows:

Value range instructions
singleton Default value, singleton
prototype Many cases
request In a WEB project, Spring creates an object of a Bean and stores the object into the Request domain
session In a WEB project, Spring creates an object of a Bean and stores the object into the Session domain
global session In WEB projects, applied in a Portlet environment, globalSession is equivalent to a session if there is no Portlet environment
When the Spring core file is loaded, instantiate the configured Bean instance. Life cycle of the Bean: Object creation: When the application is loaded and the container is created, the object is created. Object run: Object destruction: When the application is unloaded and the container is destroyed, the object is destroyed. 2. When the getBean() method is called. Life cycle of the Bean: Object creation: When an object is used, a new object instance is created. The object runs: Object destruction: When an object is not used for a long time, it is collected by the Java garbage collectorCopy the code

Bean lifecycle configuration

<bean id="" class="" scope="" init-method="" destroy-method=""></bean>* init-method: specifies the name of the initialization method in the class * destroy-method: specifies the name of the destruction method in the classCopy the code

Beans can be instantiated in three ways

  • Instantiate the no-argument constructor
  • Factory static method instantiation
  • Factory common method instantiation

Instantiate the no-argument constructor

It creates the class object based on the default no-argument constructor, which will fail if there is no default no-argument constructor in the bean

<bean id="userDao" class="com.lagou.dao.impl.UserDaoImpl"/>
Copy the code

Factory static method instantiation

  • Application scenarios

Class A has A static method m1 whose return value is A B object. If we use B objects frequently, we can hand over the creation of B objects to Spring’s IOC container, so that we can use B objects directly from the IOC container in the future without calling the M1 method of class A.

public class StaticFactoryBean {

    public static UserDao createUserDao(a){
        return newUserDaoImpl(); }}Copy the code
<bean id="userDao" class="com.lagou.factory.StaticFactoryBean"
        factory-method="createUserDao" />
Copy the code

Factory common method instantiation

  • Application scenarios

Class A has A common method m1, whose return value is A B object. If we use B objects frequently, we can hand over the creation of B objects to Spring’s IOC container, so that we can use B objects directly from the IOC container in the future without calling the M1 method of class A.

public class DynamicFactoryBean {

    public UserDao createUserDao(a){
        return newUserDaoImpl(); }}Copy the code
<bean id="dynamicFactoryBean" class="com.lagou.factory.DynamicFactoryBean"/>
<bean id="userDao" factory-bean="dynamicFactoryBean" factory-method="createUserDao"/>
Copy the code

Bean dependency injection Overview

Dependency Injection DI (DI) : It is a concrete implementation of IOC, the core of the Spring framework.

When you write your program, you leave the creation of the object to Spring through inversion of control, but you can’t have code that doesn’t have dependencies. IOC decoupling only reduces their dependencies, but does not eliminate them. For example, the business layer still calls the methods of the persistence layer.

The dependency between the business layer and the persistence layer will be maintained by Spring after Spring is used. In simple terms, the persistence layer object is passed to the business layer through the framework without having to fetch it ourselves.

Bean dependency injection mode

A constructor

Create a parameter construct in UserServiceImpl

public class UserServiceImpl implements UserService {

    private UserDao userDao;

    public UserServiceImpl(UserDao userDao) {
        this.userDao = userDao;
    }

    @Override
    public void save(a) { userDao.save(); }}Copy the code

Configure injection when the Spring container calls a parameter construct

<bean id="userDao" class="com.lagou.dao.impl.UserDaoImpl"/>
<bean id="userService" class="com.lagou.service.impl.UserServiceImpl">
    <! --<constructor-arg index="0" type="com.lagou.dao.UserDao" ref="userDao"/>-->
    <constructor-arg name="userDao" ref="userDao"/>
</bean>
Copy the code

Set method

Create the set method in UserServiceImpl

public class UserServiceImpl implements UserService {

    private UserDao userDao;

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    @Override
    public void save(a) { userDao.save(); }}Copy the code

Configure the Spring container to call the set method for injection

<bean id="userDao" class="com.lagou.dao.impl.UserDaoImpl"/>
<bean id="userService" class="com.lagou.service.impl.UserServiceImpl">
    <property name="userDao" ref="userDao"/>
</bean>
Copy the code

P namespace injection

P namespace injection is also set injection, but it is more convenient than the above set injection, which is mainly reflected in the configuration file as follows:

First, we need to introduce the P namespace:

xmlns:p="http://www.springframework.org/schema/p"
Copy the code

Second, you need to modify the injection mode:

<bean id="userDao" class="com.lagou.dao.impl.UserDaoImpl"/>
<bean id="userService" class="com.lagou.service.impl.UserServiceImpl"
      p:userDao-ref="userDao"/>
Copy the code

The data type of Bean dependency injection

All of the above operations inject Bean objects. In addition to the reference of the object, ordinary data types and collections can be injected into the container.

Three data types for injecting data

  1. Common data types
  2. Reference data type
  3. Set data type

It refers to the data type, which I won’t go into here; the previous operations injected references to the UserDao object. The following uses the set method injection as an example to demonstrate the injection of common and collection data types.

Inject normal data types

public class User {
    private String username;
    private String age;

    public void setUsername(String username) {
        this.username = username;
    }

    public void setAge(String age) {
        this.age = age; }}Copy the code
<bean id="user" class="com.lagou.domain.User">
    <property name="username" value="jack"/>
    <property name="age" value="18"/>
</bean>
Copy the code

Inject collection data types

1) List collection injection

public class UserDaoImpl implements UserDao {

    private List<Object> list;

    public void save(a) {
        System.out.println(list);
        System.out.println("Saved successfully..."); }}Copy the code
<bean id="user" class="com.lagou.domain.User">
    <property name="username" value="jack"/>
    <property name="age" value="18"/>
</bean>
<bean id="userDao" class="com.lagou.dao.impl.UserDaoImpl">
    <property name="list">
        <list>
            <value>aaa</value>
            <ref bean="user"></ref>
        </list>
    </property>
</bean>
Copy the code

2) Set collection injection

public class UserDaoImpl implements UserDao {

    private Set<Object> set;

    public void setSet(Set<Object> set) {
        this.set = set;
    }

    public void save(a) {
        System.out.println(set);
        System.out.println("Saved successfully..."); }}Copy the code
<bean id="user" class="com.lagou.domain.User">
    <property name="username" value="jack"/>
    <property name="age" value="18"/>
</bean>
<bean id="userDao" class="com.lagou.dao.impl.UserDaoImpl">
    <property name="set">
        <list>
            <value>bbb</value>
            <ref bean="user"></ref>
        </list>
    </property>
</bean>
Copy the code

3) Array injection

public class UserDaoImpl implements UserDao {

    private Object[] array;

    public void setArray(Object[] array) {
        this.array = array;
    }

    public void save(a) {
        System.out.println(Arrays.toString(array));
        System.out.println("Saved successfully..."); }}Copy the code
<bean id="user" class="com.lagou.domain.User">
    <property name="username" value="jack"/>
    <property name="age" value="18"/>
</bean>
<bean id="userDao" class="com.lagou.dao.impl.UserDaoImpl">
    <property name="array">
        <array>
            <value>ccc</value>
            <ref bean="user"></ref>
        </array>
    </property>
</bean>
Copy the code

4) Map collection injection

public class UserDaoImpl implements UserDao {

    private Map<String, Object> map;

    public void setMap(Map<String, Object> map) {
        this.map = map;
    }

    public void save(a) {
        System.out.println(map);
        System.out.println("Saved successfully..."); }}Copy the code
<bean id="user" class="com.lagou.domain.User">
    <property name="username" value="jack"/>
    <property name="age" value="18"/>
</bean>
<bean id="userDao" class="com.lagou.dao.impl.UserDaoImpl">
    <property name="map">
        <map>
            <entry key="k1" value="ddd"/>
            <entry key="k2" value-ref="user"></entry>
        </map>
    </property>
</bean>
Copy the code

5) Properties configure injection

public class UserDaoImpl implements UserDao {

    private Properties properties;

    public void setProperties(Properties properties) {
        this.properties = properties;
    }

    public void save(a) {
        System.out.println(properties);
        System.out.println("Saved successfully..."); }}Copy the code
<bean id="userDao" class="com.lagou.dao.impl.UserDaoImpl">
    <property name="properties">
        <props>
            <prop key="k1">v1</prop>
            <prop key="k2">v2</prop>
            <prop key="k3">v3</prop>
        </props>
    </property>
</bean>
Copy the code

Configuration file modularization

In practice, there is a lot of configuration in Spring, which leads to a lot of complexity and volume, so you can break some of the configuration into other configuration files, which is called configuration file modularization.

1) Parallel configuration files

ApplicationContext act =
                new
ClassPathXmlApplicationContext("beans1.xml"."beans2.xml"."...");
Copy the code

2) Master/slave configuration files

<import resource="applicationContext-xxx.xml"/>
Copy the code

Note:

  • Beans with the same name cannot appear in the same XML; if they do, an error will be reported
  • Multiple XML files with beans of the same name will not report an error, but the loaded bean will overwrite the loaded bean

Knowledge summary

Key configuration for Spring

<bean>Class attribute: Fully qualified name of the Bean to be instantiated. Scope attribute: scope of the Bean. Common examples are Singleton(default) and Prototype<constructor-arg>Label: injected attribute Name Attribute name value Attribute: injected common attribute value ref attribute: injected object reference value<property>Label: injected attribute Name Attribute name value Attribute: injected common attribute value ref attribute: injected object reference value<list>
    <set>
    <array>
    <map>
    <props>

<import>Tag: Import other Spring filesCopy the code

DbUtils (IOC practice)

What are DbUtils?

DbUtils is an Apache utility class for simplifying Dao code. It encapsulates JDBC technology at the bottom.

Core object

QueryRunner queryRunner = new QueryRunner(DataSource dataSource);
Copy the code

Core method

int update(a); Execute add, delete, and modify statementsT query(a); ResultSetHandler<T> This is an interface that encapsulates the records returned by the database into entity objectsCopy the code

Take a chestnut

Example Query information about all accounts in the database to the Account entity

public class DbUtilsTest {

    @Test
    public void findAllTest(a) throws Exception {
        // Create the DBUtils utility class and pass in the connection pool
        QueryRunner queryRunner = new QueryRunner(JdbcUtils.getDataSource());
        / / write SQL
        String sql = "select * from account";
        / / SQL execution
        List<Account> list = queryRunner.query(sql, new BeanListHandler<Account>(Account.class));
        // Print the result
        for(Account account : list) { System.out.println(account); }}}Copy the code

Spring’s XML integration DbUtils

introduce

  • demand

Implement CRUD cases for accounts based on Spring’s XML configuration

  • Step analysis
1. Prepare the database environment 2. Create a Java project and import coordinates 3. 4. Write the AccountDao interface and implementation class 5. Write the AccountService interface and implementation class 6. Write the Spring core configuration file 7. Write test codeCopy the code

implementation

1) Prepare the database environment

CREATE DATABASE `spring_db`;

USE `spring_db`;

CREATE TABLE `account` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `name` varchar(32) DEFAULT NULL.`money` double DEFAULT NULL,
    PRIMARY KEY (`id`));insert into `account`(`id`.`name`.`money`) values (1.'tom'.1000), (2.'jerry'.1000);
Copy the code

2) Create a Java project and import coordinates

<dependencies>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.47</version>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.1.9</version>
    </dependency>
    <dependency>
        <groupId>commons-dbutils</groupId>
        <artifactId>commons-dbutils</artifactId>
        <version>1.6</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.1.5. RELEASE</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
</dependencies>
Copy the code

3) Write the Account entity class

public class Account {

    private Integer id;
    private String name;
    private Double money;

}
Copy the code

4) Write the AccountDao interface and implementation class

public interface AccountDao {

    public List<Account> findAll(a);

    public Account findById(Integer id);

    public void save(Account account);

    public void update(Account account);

    public void delete(Integer id);

}
Copy the code
public class AccountDaoImpl implements AccountDao {

    private QueryRunner queryRunner;

    public void setQueryRunner(QueryRunner queryRunner) {
        this.queryRunner = queryRunner;
    }

    @Override
    public List<Account> findAll(a) {
        List<Account> list = null;
        / / write SQL
        String sql = "select * from account";
        try {
            / / SQL execution
            list = queryRunner.query(sql, new BeanListHandler<Account>(Account.class));
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return list;
    }

    @Override
    public Account findById(Integer id) {
        Account account = null;
        / / write SQL
        String sql = "select * from account where id = ?";
        try {
            / / SQL execution
            account = queryRunner.query(sql, new BeanHandler<Account>(Account.class), id);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return account;
    }

    @Override
    public void save(Account account) {
        / / write SQL
        String sql = "insert into account values(null,? ,?) ";
        / / SQL execution
        try {
            queryRunner.update(sql, account.getName(), account.getMoney());
        } catch(SQLException e) { e.printStackTrace(); }}@Override
    public void update(Account account) {
        / / write SQL
        String sql = "update account set name = ? ,money = ? where id = ?";
        / / SQL execution
        try {
            queryRunner.update(sql, account.getName(),account.getMoney(),account.getId());
        } catch(SQLException e) { e.printStackTrace(); }}@Override
    public void delete(Integer id) {
        / / write SQL
        String sql = "delete from account where id = ?";
        / / SQL execution
        try {
            queryRunner.update(sql, id);
        } catch(SQLException e) { e.printStackTrace(); }}}Copy the code

5) Write the AccountService interface and implementation class

public interface AccountService {

    public List<Account> findAll(a);

    public Account findById(Integer id);

    public void save(Account account);

    public void update(Account account);

    public void delete(Integer id);
}
Copy the code
public class AccountServiceImpl implements AccountService {

    private AccountDao accountDao;

    public void setAccountDao(AccountDao accountDao) {
        this.accountDao = accountDao;
    }

    @Override
    public List<Account> findAll(a) {
        return accountDao.findAll();
    }

    @Override
    public Account findById(Integer id) {
        return accountDao.findById(id);
    }

    @Override
    public void save(Account account) {
        accountDao.save(account);
    }

    @Override
    public void update(Account account) {
        accountDao.update(account);
    }

    @Override
    public void delete(Integer id) { accountDao.delete(id); }}Copy the code

6) Write the Spring core configuration file

applicationContext.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">

    <! Give the database connection pool to the IOC container
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://localhost:3306/spring_db"></property>
        <property name="username" value="root"></property>
        <property name="password" value="root"></property>
    </bean>
    <! Pass QueryRunner to IOC container -->
    <bean id="queryRunner" class="org.apache.commons.dbutils.QueryRunner">
        <constructor-arg name="ds" ref="dataSource"></constructor-arg>
    </bean>
    <! Give AccountDao to IOC container -->
    <bean id="accountDao" class="com.lagou.dao.impl.AccountDaoImpl">
        <property name="queryRunner" ref="queryRunner"></property>
    </bean>
    <! Give AccountService to the IOC container -->
    <bean id="accountService" class="com.lagou.service.impl.AccountServiceImpl">
        <property name="accountDao" ref="accountDao"></property>
    </bean>
</beans>
Copy the code

7) Write test code

public class AccountServiceTest {

    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
    AccountService accountService = applicationContext.getBean(AccountService.class);

    // Test save
    @Test
    public void testSave(a) {
        Account account = new Account();
        account.setName("lucy");
        account.setMoney(100d);
        accountService.save(account);
    }

    // Test the query
    @Test
    public void testFindById(a) {
        Account account = accountService.findById(3);
        System.out.println(account);
    }

    // Test query all
    @Test
    public void testFindAll(a) {
        List<Account> accountList = accountService.findAll();
        for(Account account : accountList) { System.out.println(account); }}// Test the modification
    @Test
    public void testUpdate(a) {
        Account account = new Account();
        account.setId(3);
        account.setName("jack");
        account.setMoney(2000d);
        accountService.update(account);
    }

    // Test delete
    @Test
    public void testDelete(a) {
        accountService.delete(3); }}Copy the code

8) Extract the JDBC configuration file

Applicationcontext.xml loads the jdbc.properties configuration file for connection information.

First, we need to introduce the context namespace and constraint path:

: * namespace XMLNS: context = "http://www.springframework.org/schema/context" * constraint path:  http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsdCopy the code
<context:property-placeholder location="classpath:jdbc.properties"/>

<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
    <property name="driverClassName" value="${jdbc.driver}"></property>
    <property name="url" value="${jdbc.url}"></property>
    <property name="username" value="${jdbc.username}"></property>
    <property name="password" value="${jdbc.password}"></property>
</bean>
Copy the code

Knowledge summary

The Spring container loads the properties file for the DataSource using the constructor<context:property-placeholder location="xx.properties"/>
    <property name="" value="${key}"/>
Copy the code

Spring Annotation Development

Spring is a framework that is light in code but heavy in configuration, which is heavy in configuration and affects development efficiency. Therefore, annotation development is a trend. Annotations instead of XML configuration files can simplify configuration and improve development efficiency.

Spring Spring

introduce

Spring common annotations are mainly used to replace the configuration of <bean>

annotations instructions
@Component Used to instantiate beans on a class
@Controller Used to instantiate beans on web layer classes
@Service Used to instantiate beans on service layer classes
@Repository Used to instantiate beans on dao layer classes
@Autowired Used on fields for dependency injection by type
@Qualifier Used in conjunction with @autowired, dependency injection by name
@Resource Equivalent to @autowired +@Qualifier, injected by name
@Value Injecting common properties
@Scope The scope of the annotation Bean
@PostConstruct Use the annotation on a method that is the Bean’s initialization method
@PreDestroy Use the annotation on the method that the method is the Bean’s destruction method
  • Description:

The @Resource annotation cannot be used because javax extensions have been completely removed in JDK11

Maven is required to introduce dependencies<dependency>
    <groupId>javax.annotation</groupId>
    <artifactId>javax.annotation-api</artifactId>
    <version>1.3.2</version>
</dependency>
Copy the code
  • Pay attention to

When developing with annotations, you configure component scanning in applicationContext.xml to specify which package and beans under its subpackages need to be scanned to identify classes, fields, and methods configured with annotations.

<! -- Component scan for annotations -->
<context:component-scan base-package="com.lagou"></context:component-scan>
Copy the code

implementation

1) Bean instantiation (IOC)

<bean id="userDao" class="com.lagou.dao.impl.UserDaoImpl"></bean>
Copy the code

Using @Compont or @Repository to identify UserDaoImpl requires Spring to instantiate.

// @Component(value = "userDao")
@Repository // If the value attribute value is not written, the Bean id is: class name lowercase
public class UserDaoImpl implements UserDao {}Copy the code

Property dependency Injection (DI)

<bean id="userService" class="com.lagou.service.impl.UserServiceImpl">
    <property name="userDao" ref="userDaoImpl"/>
</bean>
Copy the code

Inject the userDao using @autowired or @Autowired+ @qulifier or @Resource

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDao userDao;

    // <property name="userDao" ref="userDaoImpl"/>
    // @Autowired
    // @Qualifier("userDaoImpl")
    // @Resource(name = "userDaoImpl")
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao; }}Copy the code

3) @ the Value

String injection using @value, combined with SPEL expression to get configuration parameters

@Service
public class UserServiceImpl implements UserService {

    @value (" Inject normal data ")
    private String str;
    @Value("${jdbc.driver}")
    private String driver;

}
Copy the code

4) @ the Scope

<bean scope=""/>
Copy the code

Annotate the Scope of the Bean with @scope

@Service
@Scope("singleton")
public class UserServiceImpl implements UserService {{}Copy the code

5) Bean life cycle

<bean init-method="init" destroy-method="destory" />
Copy the code

Use the @postConstruct annotation to initialize the method and the @preDestroy annotation to destroy the method

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

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

Spring commonly used annotations integrate DbUtils

Step analysis

Modify the AccountDaoImpl implementation class. 3. Modify the AccountServiceImpl implementation Class. 4. Modify the Spring core configuration file. Write test codeCopy the code

1) Copy the XML configuration project and change it to the common annotations configuration project

2) Modify the AccountDaoImpl implementation class

@Repository
public class AccountDaoImpl implements AccountDao {

    @Autowired
    privateQueryRunner queryRunner; . }Copy the code

3) Modify the AccountServiceImpl implementation class

@Service
public class AccountServiceImpl implements AccountService {

    @Autowired
    privateAccountDao accountDao; . }Copy the code

4) Modify the Spring core configuration file


      
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w1.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <! -- Component scan for annotations -->
    <context:component-scan base-package="com.lagou"></context:component-scan>

    <! Load the JDBC configuration file -->
    <context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>

    <! Give the database connection pool to the IOC container
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${jdbc.driver}"></property>
        <property name="url" value="${jdbc.url}"></property>
        <property name="username" value="${jdbc.username}"></property>
        <property name="password" value="${jdbc.password}"></property>
    </bean>
    <! Pass QueryRunner to IOC container -->
    <bean id="queryRunner" class="org.apache.commons.dbutils.QueryRunner">
        <constructor-arg name="ds" ref="dataSource"></constructor-arg>
    </bean>
</beans>
Copy the code

5) Write test code

public class AccountServiceTest {

    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
    AccountService accountService = applicationContext.getBean(AccountService.class);

    // Test the query
    @Test
    public void findByIdTest(a) {
        Account account = accountService.findById(3); System.out.println(account); }}Copy the code

Spring new annotation

Not all XML configuration files can be replaced with the above annotations, but the following configurations need to be replaced with annotations:

* Non-custom Bean configuration: < Bean > * Loading properties file configuration: <context:property-placeholder> * Component scan configuration: <context:component-scan> * Importing other files: <import>Copy the code
annotations instructions
@Configuration Used to specify that the current class is a Spring configuration class from which annotations will be loaded when the container is created
@Bean With a method, the annotation stores the return value of that method in the Spring container
@PropertySource Used to load the configuration in the properties file
@ComponentScan Used to specify the packages to be scanned by Spring when the container is initialized
@Import Used to import other configuration classes

Spring pure annotations integrate with DbUtils

Step analysis

1. Write Spring core configuration class 2. Write database configuration information class 3. Write test codeCopy the code

1) Write Spring core configuration classes

@Configuration
@ComponentScan("com.lagou")
@Import(DataSourceConfig.class)
public class SpringConfig {

    @Bean("queryRunner")
    public QueryRunner getQueryRunner(@Autowired DataSource dataSource) {
        return newQueryRunner(dataSource); }}Copy the code

2) Write the database configuration information class

@PropertySource("classpath:jdbc.properties")
public class DataSourceConfig {
    @Value("${jdbc.driver}")
    private String driver;
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.username}")
    private String username;
    @Value("${jdbc.password}")
    private String password;

    @Bean("dataSource")
    public DataSource getDataSource(a) {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(driver);
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        returndataSource; }}Copy the code

3) Write test code

public class AccountServiceTest {

    ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfig.class);
    AccountService accountService = applicationContext.getBean(AccountService.class);

    // Test the query
    @Test
    public void testFindById(a) {
        Account account = accountService.findById(3); System.out.println(account); }}Copy the code

Spring integration Junit

General Junit test issues

In a normal test class, the developer manually loads the configuration file and creates the Spring container, and then obtains the Bean instance through the Spring-related API. If you don’t, you can’t get the object from the container.

ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");

AccountService accountService = applicationContext.getBean(AccountService.class);
Copy the code

We can simplify this by making SpringJunit responsible for creating the Spring container. Developers can inject Bean instances directly into the test class; But you need to tell it the name of the configuration file.

Spring integration Junit

Step analysis

1. Import spring integration Junit coordinates 2. Replace the original runner with @runwith annotation 3. Using @contextConfiguration to specify a configuration file or configuration class 4. 5. Create a test method to testCopy the code

1) Import spring integration Junit coordinates

<! Junit must be 4.12 or later for spring5 or later.
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>5.1.5. RELEASE</version>
</dependency>
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
</dependency>
Copy the code

2) Replace the original runner with the @runwith annotation

@RunWith(SpringJUnit4ClassRunner.class)
public class SpringJunitTest {}Copy the code

3) Specify the configuration file or configuration class using @contextConfiguration

@RunWith(SpringJUnit4ClassRunner.class)
/ / @ ContextConfiguration (value = {" classpath: applicationContext. XML "}) loaded spring core configuration file
@ContextConfiguration(classes = {SpringConfig.class}) // Load the Spring core configuration class
public class SpringJunitTest {}Copy the code

4) Inject objects to be tested using @autoWired

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {SpringConfig.class})
public class SpringJunitTest {

    @Autowired
    private AccountService accountService;
}
Copy the code

5) Create test methods to test

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {SpringConfig.class})
public class SpringJunitTest {

    @Autowired
    private AccountService accountService;

    // Test the query
    @Test
    public void testFindById(a) {
        Account account = accountService.findById(3); System.out.println(account); }}Copy the code