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
Problems with the original Junit test Spring
Ideas for solving the above problems
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
- Import coordinates of the data source and database-driven coordinates
- Create Data Source Object
- Setting up the basic connection data for the data source
- 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
- Import spring integration Junit coordinates
- Replace the original run time with the @Runwith comment
- Specify a profile or configuration class using @ContextConfiguration
- Injecting objects that need to be tested using @Autowired
- 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
- Import spring integration Junit coordinates
- Replace the original run time with the @Runwith comment
- Specify a profile or configuration class using @ContextConfiguration
- Injecting objects that need to be tested using @Autowired
- Create test methods for testing