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
- 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
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
annotation | Explain |
---|---|
@Component | Used 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 |
@Controller | Used on a Web-tier class to instantiate a Bean |
@Service | Used on the Service layer class to instantiate beans |
@Repository | Used on the dao layer class to instantiate beans |
@Autowired | Used on fields for type-dependent injection |
@Qualifier | Used in conjunction 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 | Using the method, labeling the method is the Bean's initialization method |
@PreDestroy | Using 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>
annotation | Explain |
---|---|
@Configuration | Used to specify that the current class is a Spring configuration class that loads annotations from the class when creating containers |
@ComponentScan | Used 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 |
@Bean | Using a method, the label stores the method's return value in the Spring container |
@PropertySource | For loading. Configuration in the properties file |
@Import | For 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
-
Import coordinates of Spring integrated Junit
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>5.3.16</version> </dependency>
-
Replace the original run time with the @RunWith(SpringJUnit4ClassRunner.class) annotation
-
Specify a profile or configuration class using @ContextConfiguration
-
Injecting objects that need to be tested using @Autowired
-
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()); } }