Spring Annotation Development

Keywords: Java Spring Framework

Catalog

Spring Configuration Data Source

Role of data sources (connection pools)

Steps for developing data sources

  Manual creation of data sources

  Spring Configuration Data Source

  Extract jdbc configuration file

Spring Annotation Development

Spring original annotations

New Spring Notes  

Spring Integrated Junit

Problems with the original Junit test Spring

  Ideas for solving the above problems

Spring Integrated Junit Step  

  Spring Integrated Junit Code Implementation

Spring Configuration Data Source

Role of data sources (connection pools)

  • Data sources (connection pools) are available 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

1. Import c3p0, druid, junit, and mysql database-driven coordinates

    <dependencies>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.10</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.25</version>
        </dependency>

        <dependency>
            <groupId>com.mchange</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.5.2</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

  (2) Create C3P0 connection pool

    @Test
    //Test Manual Creation of c3p0 Data Source
    public void test1() throws PropertyVetoException, SQLException {
        //create data source
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        //Setting database connection parameters
        dataSource.setDriverClass("com.mysql.jdbc.Driver");
        dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test");
        dataSource.setUser("root");
        dataSource.setPassword("123456");
        //Get Connection Object
        Connection connection = dataSource.getConnection();
        System.out.println(connection);
        //Return Connected Resources
        connection.close();
    }

  (2) Create Druid connection pool

    @Test
    //Test Manually Create druid Data Source
    public void test2() throws Exception {
        //create data source
        DruidDataSource dataSource = new DruidDataSource();
        //Setting database connection parameters
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/test");
        dataSource.setUsername("root");
        dataSource.setPassword("123456");
        //Get Connection Object
        DruidPooledConnection connection = dataSource.getConnection();
        System.out.println(connection);
        //Return Connected Resources
        connection.close();
    }

  (3) Extracting jdbc.properties configuration file

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test
jdbc.username=root
jdbc.password=123456

  (4) Read jdbc.properties configuration file to create connection pool

    @Test
    //Test Manually Create c3p0 Data Source (Load Properrties Profile)
    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);
        //Get Connection Object
        Connection connection = dataSource.getConnection();
        System.out.println(connection);
        //Return Connected Resources
        connection.close();

    }

  Spring Configuration Data Source

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

  • DataSource has parameterized construction methods, and Spring instantiates objects by default with parameterized construction methods
  • DataSource uses the set method to set the database connection information, while Spring uses the set method for string injection
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test"></property>
        <property name="user" value="root"></property>
        <property name="password" value="123456"></property>
    </bean>

  Test Getting Data Sources from Containers

    @Test
    //Test spring Container to Generate Data Source Objects
    public void test4() throws Exception {
        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
        //DataSource dataSource = (DataSource)app.getBean("dataSource"); 
        DataSource dataSource = app.getBean(DataSource.class);
        Connection connection = dataSource.getConnection();
        System.out.println(connection);
        connection.close();

    }

  Extract jdbc configuration file

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

First, you 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.xsd
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd ">

    <!--Loading external properties file-->
    <context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>

    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${jdbc.driver}"></property>
        <property name="jdbcUrl" value="${jdbc.url}"></property>
        <property name="user" value="${jdbc.username}"></property>
        <property name="password" value="${jdbc.password}"></property>
    </bean>
</beans>

  Key Points of Knowledge

Spring Container Load properties File

Spring Annotation Development

Spring original annotations

Spring is a framework of light code and reconfiguration, which is heavy to configure and affects development efficiency, so 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>configuration

annotation

Explain

   @Component

Use for instantiating beans on classes

   @Controller

Use for instantiating beans on web-tier classes

   @Service

Use for instantiating beans on service layer classes

   @Repository

Use for instantiating beans on dao layer classes

   @Autowired

Use on fields for type-dependent injection

   @Qualifier

Used with @Autowired for dependency injection by name

   @Resource

Equivalent to @Autowired+@Qualifier, injected by name

   @Value

Injecting generic attributes

   @Scope

Scope of label beans

   @PostConstruct

Labeling the method using the method is the Bean's initialization method

   @PreDestroy

Label the method as Bean's destruction method using the method

Be careful:

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

    <!--Configure Component Scan-->
    <context:component-scan base-package="com.shengda"></context:component-scan>

  Identifying UserDaoImpl with @Compont or @Repository requires Spring to instantiate.

package com.shengda.dao.impl;

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

//<bean id="userDao" class="com.shengda.dao.impl.UserDaoImpl"></bean>
//@Component("userDao")
@Repository("userDao")
public class UserDaoImpl implements UserDao {
    @Override
    public void save() {
        System.out.println("save running...");
    }
}

Identifying UserServiceImpl with @Compont or @Service requires Spring for instantiation

userDao injection using @Autowired or @Autowired+@Qulifier or @Resource

package com.shengda.service.impl;

import com.shengda.dao.UserDao;
import com.shengda.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

//<bean id="userService" class="com.shengda.service.impl.UserServiceImpl"></bean>
//@Component("userService")
@Service("userService")
public class UserServiceImpl implements UserService {
    //Inject both userdao and service into the container
    //<property name="userDao" ref="userDao"></property>
    /*@Autowired  //Match from Spring container by data type
    @Qualifier("userDao")   //Match from container according to id value and use with @Autowired*/
    @Resource(name = "userDao")   //Equivalent to @Autowired+@Qualifier
    private UserDao userDao;
    //Annotation can omit the set method, xml needs to be written
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    @Override
    public void save() {
        userDao.save();
    }
}

  String injection using @Value

    @Value("${jdbc.driver}")
    private String drive;
    @Resource(name = "userDao")   //Equivalent to @Autowired+@Qualifier
    private UserDao userDao;
    //Annotation can omit the set method, xml needs to be written
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    @Override
    public void save() {
        System.out.println(drive);
        userDao.save();
    }

Label Bean's range with @Scope

@Service("userService")
//@Scope("prototype")
@Scope("singleton")
public class UserServiceImpl implements UserService {
}

  Use @PostConstruct label initialization method and @PreDestroy label destroy method

    @PostConstruct
    public void init(){
        System.out.println("Initialization Method");
    }
    @PreDestroy
    public void destory(){
        System.out.println("destroy-method");
    }

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>

annotation

Explain

   @Configuration

Used to specify that the current class is a Spring configuration class from which annotations are loaded when creating containers

   @ComponentScan

Used to specify the package that Spring will scan when initializing the container.

Role and in Spring's xml configuration file

<context:component-scan base-package="com.itheima"/>the same

   @Bean

Using a method, the label stores the method's return value in the Spring container

   @PropertySource

Configuration used to load.properties files

   @Import

For importing other configurations

  • @Configuration
  • @ComponentScan
  • @Import
package com.shengda.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

//Core Configuration Class
@Configuration
//Configure Component Scan
@ComponentScan("com.shengda")
//Import Allocation File
@Import(DataSourceConfiuration.class)
public class SpringConfiguration {
}
  • @PropertySource
  • @value
  •  @Bean

package com.shengda.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;

@PropertySource("classpath:jdbc.properties")
public class DataSourceConfiuration {
    @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 getresource() throws PropertyVetoException {
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        //Setting database connection parameters
        dataSource.setDriverClass(driver);
        dataSource.setJdbcUrl(url);
        dataSource.setUser(username);
        dataSource.setPassword(password);
        return dataSource;
    }
}

  Test Load Core Configuration Class Create Spring Container

package com.shengda.web;

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

public class UserController {
    public static void main(String[] args) {
        //ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
        ApplicationContext app = new AnnotationConfigApplicationContext(SpringConfiguration.class);
        UserService userService = app.getBean(UserService.class);
        userService.save();
    }
}

Spring Integrated Junit

Problems with the original Junit test Spring

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

    ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");

    AccountService 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.

  Ideas for solving the above problems

  • Let SpringJunit be responsible for creating the Spring container, but you need to tell it the name of the configuration file
  • Test Bean s will need to be injected directly into the test class

Spring Integrated Junit Step  

  1. Import spring integration Junit coordinates
  2. Replace the original run time with the @Runwith comment
  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

  Spring Integrated Junit Code Implementation

1. Import spring integrated Junit coordinates

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

        
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.3.5</version>
        </dependency>

(2) Replace the original run time with the @Runwith comment  

import org.junit.runner.RunWith;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
public class DataJunitTest {
}

  (3) Use @ContextConfiguration to specify profiles or configuration classes

import org.junit.runner.RunWith;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
//Load Profile
//@ContextConfiguration("classpath:applicationContext.xml")
//Full Annotation Method
@ContextConfiguration(classes = {SpringConfiguration.class})
public class DataJunitTest {
}

  (4) Injecting objects that need to be tested with @Autowired

public class DataJunitTest {
    @Autowired
    private UserService userService;

    @Autowired
    private DataSource dataSource;

   
}

  Create test methods for testing

package com.shengda.test;

import com.shengda.config.SpringConfiguration;
import com.shengda.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;

@RunWith(SpringJUnit4ClassRunner.class)
//Load Profile
//@ContextConfiguration("classpath:applicationContext.xml")
//Full Annotation Method
@ContextConfiguration(classes = {SpringConfiguration.class})
public class DataJunitTest {
    @Autowired
    private UserService userService;

    @Autowired
    private DataSource dataSource;

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

  Key Points of Knowledge

Spring Integrated Junit Step

  1. Import spring integration Junit coordinates
  2. Replace the original run time with the @Runwith comment
  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

Posted by phphelpme on Fri, 19 Nov 2021 17:41:43 -0800