Spring Quick Start - Configuring Data Sources & Note Development

Spring Configuration Data Source

Role of data sources (connection pools)

  • Data sources (connection pools) occur to improve program performance
  • Pre-instantiate the data source to initialize partial connection resources
  • Get from data source when using connection resources
  • Return the connected resource to the data source after use
  • Common data sources (connection pools): DBCP, C3P0, BoneCP, Druid, etc.

Steps for developing data sources

  1. Import coordinates of the data source and database-driven coordinates
  2. Create Data Source Object
  3. Setting up the basic connection data for the data source
  4. Getting and returning connection resources using data sources

Manual creation of data sources

import com.alibaba.druid.pool.DruidDataSource;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.junit.Test;

import java.sql.Connection;
import java.util.ResourceBundle;

public class DataSourceTest {
    /*
     * @Date: 2022/3/2 12:18
     * Test Manual Creation of c3p0 Data Source
     */
    @Test
    public void test1() throws Exception {
        //Create data source dataSource
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        //Set basic connection parameters: driver, url, user, password
        dataSource.setDriverClass("com.mysql.cj.jdbc.Driver");
        dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/db1?serverTimezone=Asia/Shanghai");
        dataSource.setUser("root");
        dataSource.setPassword("123456");
        //Get connection resources through dataSource
        Connection connection = dataSource.getConnection();
        System.out.println(connection);
        //Return Connected Resources
        connection.close();
    }
    /*
     * @Date: 2022/3/2 12:39
     * Test Create Druid Data Source Manually
     */
    @Test
    public void test2() throws Exception {
        //Create data source dataSource
        DruidDataSource dataSource = new DruidDataSource();
        //Set basic connection parameters: driver, url, user, password
        dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/db1?serverTimezone=Asia/Shanghai");
        dataSource.setUsername("root");
        dataSource.setPassword("123456");
        //Get connection resources through dataSource
        Connection connection = dataSource.getConnection();
        System.out.println(connection);
        //Return Connected Resources
        connection.close();
    }

    /*
     * @Date: 2022/3/2 12:46
     * Test Manually Create c3p0 Data Source (Load Properrties Profile)
     */
    @Test
    public void test3() throws Exception {
        //Read Configuration File
        ResourceBundle rb = ResourceBundle.getBundle("jdbc");
        String driver = rb.getString("jdbc.driver");
        String url = rb.getString("jdbc.url");
        String username = rb.getString("jdbc.username");
        String password = rb.getString("jdbc.password");
        //Create data source objects and set connection parameters
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setDriverClass(driver);
        dataSource.setJdbcUrl(url);
        dataSource.setUser(username);
        dataSource.setPassword(password);
    }
}
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/db1?serverTimezone=Asia/Shanghai
jdbc.username=root
jdbc.password=123456

Spring Generates Data Source Objects

Creation of a DataSource can be left to the Spring container to complete

<!--with c3p0 Data source example-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    <property name="driverClass" value="com.mysql.cj.jdbc.Driver"/>
    <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/db1?serverTimezone=Asia/Shanghai"/>
    <property name="user" value="root"/>
    <property name="password" value="123456"/>
</bean>

Extract jdbc configuration file

applicationContext.xml loads jdbc. Properrties Profile for Connection Information

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

  • Namespace:

    xlmns:context="http://www.springframework.org/schema/context"
    
  • Constraint Path:

    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd
    
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       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
                           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <!--Loading external properties configuration file-->
    <context:property-placeholder location="classpath:jdbc.properties"/>
    
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <!--adopt ${}from properties Get in jdbc parameter information-->
        <property name="driverClass" value="${jdbc.driver}"/>
        <property name="jdbcUrl" value="${jdbc.url}"/>
        <property name="user" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>
</beans>

Spring Annotation Development

Spring original annotations

  • Spring is a framework of light code and reconfiguration, which is heavy to configure and affects the efficiency of development. Therefore, annotation development is a trend. Replacing xml configuration file with annotation can simplify configuration and improve development efficiency.

  • The Spring original comment is primarily a replacement for the <Bean>tag configuration

annotationExplain
@ComponentUsed on classes to instantiate beans. The last three are just like him, but they are more readable and let us know which layer this is
@ControllerUsed on a Web-tier class to instantiate a Bean
@ServiceUsed on the Service layer class to instantiate beans
@RepositoryUsed on the dao layer class to instantiate beans
@AutowiredUsed on fields for type-dependent injection
@QualifierUsed in conjunction with @Autowired for dependency injection by name
@ResourceEquivalent to @Autowired + @Qualifier, injected by name
@ValueInjecting generic attributes
@ScopeScope of label beans
@PostConstructUsing the method, labeling the method is the Bean's initialization method
@PreDestroyUsing the method, labeling the method is the Bean's destruction method

Be careful:

When developing with annotations, you need an applicationContext. Configure component scanning in XML to specify which package and the beans under it need to be scanned to identify classes, fields, and methods configured using functional annotations.

<context:component-scan base-package="com.study"/>
package com.study.dao.impl;

import com.study.dao.UserDao;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;

/**
 * @title: UserDaoImpl
 * @Author Mj
 * @Date: 2022/3/2 14:09
 * @Version 1.0
 */
//<bean id="userDao" class="com.study.dao.impl.UserDaoImpl"/>
// @Component("userDao")
@Repository("userDao")
public class UserDaoImpl implements UserDao {
    public void save() {
        System.out.println("userDao save running...");
    }
}
package com.study.service.impl;

import com.study.dao.UserDao;
import com.study.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

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

/**
 * @title: UserServiceImpl
 * @Author Mj
 * @Date: 2022/3/2 14:12
 * @Version 1.0
 */
//<bean id="userService" class="com.study.service.impl.UserServiceImpl"/>
// @Component("userService")
@Service("userService")
// @Scope("prototype")
public class UserServiceImpl implements UserService {
    /*
     * It can also be injected if only @Autowired is written
     * He is injected after matching bean s of type UserDao that have been injected from the spring container by data type
     *
     * If there are multiple bean s of the same type in the spring container now, @Autowired does not know which to inject
     *
     * @Qualifier("userDao")Is matched from container based on id value
     * Note, however, that the @Qualifier here is used in conjunction with @Autowired
     *
     * @Resource(name = "userDao")Equivalent to @Autowired + @Qualifier
     * */
    // <property name="userDao" ref="userDao"/>
    /*@Autowired
    @Qualifier("userDao")*/
    @Resource(name = "userDao")
    private UserDao userDao;

    //Injecting generic attributes
    @Value("${jdbc.driver}")
    private String driver;

    /*
    * set method is required if injection is done using xml configuration
    * With annotations, you can avoid
    * */
    // public void setUserDao(UserDao userDao) {
    //     this.userDao = userDao;
    // }

    public void save() {
        System.out.println(driver);
        userDao.save();
    }

    @PostConstruct
    public void init(){
        System.out.println("Service Object Initialization Method...");
    }

    @PreDestroy
    public void destroy(){
        System.out.println("Service Object Destroy Method...");
    }
}
package com.study.web;

import com.study.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @title: UserController
 * @Author Mj
 * @Date: 2022/3/2 14:14
 * @Version 1.0
 */
public class UserController {
    public static void main(String[] args) {
        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService = app.getBean(UserService.class);
        userService.save();
        ((ClassPathXmlApplicationContext)app).close();
    }
}

New Spring Notes

The above annotations do not completely replace the xml configuration file, and the following configurations need to be replaced by annotations:

  • Configuration of non-custom beans: <Bean>
  • Load the configuration of the properties file: <context:property-placeholder>
  • Configuration for component scan: <context:component-scan>
  • Introduce another file: <import>
annotationExplain
@ConfigurationUsed to specify that the current class is a Spring configuration class that loads annotations from the class when creating containers
@ComponentScanUsed to specify the package that Spring will scan when initializing the container. Acts like <context:component-scan base-package="com.study"/> in Spring's xml configuration file
@BeanUsing a method, the label stores the method's return value in the Spring container
@PropertySourceFor loading. Configuration in the properties file
@ImportFor importing other configuration classes
package com.study.config;

import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.PropertySource;

import javax.sql.DataSource;
import java.beans.PropertyVetoException;

/**
 * @title: DataSourceConfig
 * @Author Mj
 * @Date: 2022/3/2 17:33
 * @Version 1.0
 */

/*
    <!--Load external properties profile-->
    <context:property-placeholder location="classpath:jdbc.properties"/>
*/
@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")    //Spring stores the return value of the current method in the Spring container with the specified name
    public DataSource getDataSource() throws PropertyVetoException {
        //Create data source dataSource
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        //Set basic connection parameters: driver, url, user, password
        dataSource.setDriverClass(driver);
        dataSource.setJdbcUrl(url);
        dataSource.setUser(username);
        dataSource.setPassword(password);

        return dataSource;
    }
}
package com.study.config;

import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

import javax.sql.DataSource;
import java.beans.PropertyVetoException;

/**
 * @title: SpringConfiguration
 * @Author Mj
 * @Date: 2022/3/2 17:20
 * @Version 1.0
 */
@Configuration  //Identify this class as Spring's core profile
@Component  //<context:component-scan base-package="com.study"/>
@Import({DataSourceConfig.class})   //Load DataSourceConfig This assignment is placed in the core configuration of SpringConfiguration
public class SpringConfiguration {

}
package com.study.web;

import com.study.config.SpringConfiguration;
import com.study.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @title: UserController
 * @Author Mj
 * @Date: 2022/3/2 14:14
 * @Version 1.0
 */
public class UserController {
    public static void main(String[] args) {
        // ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
        // AnnotationConfigApplicationContext() is designed to load core configuration classes
        ApplicationContext app = new AnnotationConfigApplicationContext(SpringConfiguration.class);
        UserService userService = (UserService) app.getBean(UserService.class);
        userService.save();
        // ((ClassPathXmlApplicationContext)app).close();
    }
}

Spring Integrates Junit

Problems with the original Junit test Spring

In the test class, each test method has the following two lines of code:

//Get the object on the container
ApplicationContext app = new ClassPathXmlApplicationContext("bean.xml");
//Get the object to be tested
IAccountService as = ac.getBean("accountService",IAccountService.class);

The purpose of these two lines of code is to get the container and, if not written, prompt for a null pointer exception. Therefore, it cannot be easily deleted.

Solutions to the above problems

  • Let SpringJunit create the Spring container, but tell him the name of the configuration file
  • Test beans will need to be injected directly into the test class without going through the ApplicationContext

Spring Integrated Junit Step

  1. Import coordinates of Spring integrated Junit

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>5.3.16</version>
    </dependency>
    
  2. Replace the original run time with the @RunWith(SpringJUnit4ClassRunner.class) annotation

  3. Specify a profile or configuration class using @ContextConfiguration

  4. Injecting objects that need to be tested using @Autowired

  5. Create test methods for testing

import com.study.config.SpringConfiguration;
import com.study.service.UserService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import javax.sql.DataSource;
import java.sql.SQLException;

/**
 * @title: SpringJunitTest
 * @Author Mj
 * @Date: 2022/3/2 20:57
 * @Version 1.0
 */
@RunWith(SpringJUnit4ClassRunner.class)
//Profile Mode
// @ContextConfiguration("classpath:applicationContext.xml")
//Full Annotation Method
@ContextConfiguration(classes = {SpringConfiguration.class})
public class SpringJunitTest {

    @Autowired
    private UserService userService;

    @Autowired
    private DataSource dataSource;

    @Test
    public void test1() throws SQLException {
        userService.save();
        System.out.println("SpringJunitTest test1 running..."+dataSource.getConnection());
    }
}

Keywords: Spring mvc intellij-idea

Added by jkatcherny on Wed, 02 Mar 2022 19:25:44 +0200