SpringIoC and DI Annotation Development

1.Spring Configuration Data Source

1.1 Role of Data Source (Connection Pool)

Data sources (connection pools) are used to improve program performance, such as

Pre-instantiate the data source to initialize part of the connection resources

Getting from a data source when using connection resources

Return the connection resource to the data source after use

Common data sources (connection pools): DBCP, C3P0, BoneCP, Druid, etc.

Development steps

(1) Importing coordinates of data sources and database-driven coordinates

Creating Data Source Objects

(3) Setting up basic connection data of data source

(4) Accessing and returning connection resources by using data sources

1.2 Manual Creation of Data Sources

(1) Importing coordinates of c3p0 and druid

<!-- C3P0 Connection pool -->
<dependency>
    <groupId>c3p0</groupId>
    <artifactId>c3p0</artifactId>
    <version>0.9.1.2</version>
</dependency>
<!-- Druid Connection pool -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.10</version>
</dependency>

(1) Importing the driving coordinates of mysql database

<!-- mysql drive -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.39</version>
</dependency>

(2) Creating C3P0 Connection Pool

@Test
public void testC3P0() throws Exception {
	//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("root");
	//Get the connection object
	Connection connection = dataSource.getConnection();
	System.out.println(connection);
}

Creating Druid Connection Pool

@Test
public void testDruid() 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("root");
    //Get the connection object
    Connection connection = dataSource.getConnection();    
    System.out.println(connection);
}

(3) Extracting jdbc.properties configuration file

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

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

@Test
public void testC3P0ByProperties() throws Exception {
    //jdbc.properties under loading classpath
    ResourceBundle rb = ResourceBundle.getBundle("jdbc");
    ComboPooledDataSource dataSource = new ComboPooledDataSource(); 
    dataSource.setDriverClass(rb.getString("jdbc.driver"));   
    dataSource.setJdbcUrl(rb.getString("jdbc.url")); 
    dataSource.setUser(rb.getString("jdbc.username")); 
    dataSource.setPassword(rb.getString("jdbc.password"));
    Connection connection = dataSource.getConnection();   
    System.out.println(connection);
}

1.3 Spring Configuration Data Source

You can leave the creation of DataSource to the Spring container

DataSource has parametric constructors, and Spring by default instantiates objects through parametric constructors

Data Source needs to set up database connection information through set method to use, while Spring can inject string through set method.

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    <property name="driverClass" value="com.mysql.jdbc.Driver"/>
    <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test"/>
    <property name="user" value="root"/>
    <property name="password" value="root"/>
</bean>

Testing to get data sources from containers

ApplicationContext applicationContext = new 
           ClassPathXmlApplicationContext("applicationContext.xml");
               DataSource dataSource = (DataSource) 
applicationContext.getBean("dataSource");
Connection connection = dataSource.getConnection();
System.out.println(connection);

1.4 Extract jdbc configuration file

applicationContext.xml loads the jdbc.properties configuration file to obtain connection information.

First, context namespaces and constraint paths need to be introduced:

Namespace: xmlns:context= "http://www.spring framework.org/schema/context"

Constraint path: http://www.spring framework.org/schema/context

​ http://www.springframework.org/schema/context/spring-context.xsd

<context:property-placeholder location="classpath:jdbc.properties"/>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    <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>

1.5 Key Points of Knowledge

Spring container loads properties file

<context:property-placeholder location="xx.properties"/>
<property name="" value="${key}"/>

2. Spring annotation development

2.1 Spring original annotations

Spring is a framework of light code and reconfiguration, which has heavy configuration 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.

Spring's original annotations are primarily alternative configurations

annotation Explain
@Component Use to instantiate beans on classes
@Controller Use for instantiating beans on web-tier classes
@Service Use to instantiate beans on service layer classes
@Repository Use for instantiating beans on dao layer classes
@Autowired Use on fields for type-dependent injection
@Qualifier Used in conjunction with @Autowire for dependency injection by name
@Resource Equivalent to @Autowired+@Qualifier, injected by name
@Value Injecting common attributes
@Scope Scope of action for annotating beans
@PostConstruct Using method annotation is the initialization method of Bean
@PreDestroy Using method labeling is Bean's destruction method

Be careful:

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

<!--Annotated component scanning-->
<context:component-scan base-package="com.itheima"></context:component-scan>

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

//@Component("userDao")
@Repository("userDao")
public class UserDaoImpl implements UserDao {
    @Override
    public void save() {
    	System.out.println("save running... ...");
    }
}

Using @Compont or @Service to identify UserService Impl requires Spring to instantiate

Use @Autowire or @Autowired+@Qulifier or @Resource to inject userDao

//@Component("userService")
@Service("userService")
public class UserServiceImpl implements UserService {
    /*@Autowired
    @Qualifier("userDao")*/
    @Resource(name="userDao")
    private UserDao userDao;
    @Override
    public void save() {       
   	  userDao.save();
    }
}

Use @Value for string injection

@Repository("userDao")
public class UserDaoImpl implements UserDao {
    @Value("Injection of common data")
    private String str;
    @Value("${jdbc.driver}")
    private String driver;
    @Override
    public void save() {
        System.out.println(str);
        System.out.println(driver);
        System.out.println("save running... ...");
    }
}

Use @Scope to annotate the scope of a Bean

//@Scope("prototype")
@Scope("singleton")
public class UserDaoImpl implements UserDao {
   //Code is omitted here
}

Initialization method with @PostConstruct annotation and destruction method with @PreDestroy annotation

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

2.2 New Annotations to Spring

The above annotations can not completely replace the xml configuration file, but also need to use annotations to replace the configuration as follows:

Configuration of non-custom beans:

Load the configuration of the properties file:context:property-placeholder

Component scan configuration:context:component-scan

Introduce other documents:

annotation Explain
@Configuration Used to specify that the current class is a Spring configuration class from which annotations are loaded when a container is created
@ComponentScan Used to specify the package Spring will scan when initializing the container. It works like the <context: component-scan base-package="com.itheima"/> in Spring's xml configuration file
@Bean Using the method, the annotation stores the return value of the method in the Spring container
@PropertySource Configuration for loading. properties files
@Import For importing other configuration classes

@Configuration

@ComponentScan

@Import

@Configuration
@ComponentScan("com.itheima")
@Import({DataSourceConfiguration.class})
public class SpringConfiguration {
}

@PropertySource

@value

@PropertySource("classpath:jdbc.properties")
public class DataSourceConfiguration {
    @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

@Bean(name="dataSource")
public DataSource getDataSource() throws PropertyVetoException { 
    ComboPooledDataSource dataSource = new ComboPooledDataSource(); 
    dataSource.setDriverClass(driver);
    dataSource.setJdbcUrl(url);
    dataSource.setUser(username);
    dataSource.setPassword(password);
    return dataSource;
} 

Test Loading Core Configuration Class to Create Spring Container

@Test
public void testAnnoConfiguration() throws Exception {
ApplicationContext applicationContext = new 
          AnnotationConfigApplicationContext(SpringConfiguration.class);    UserService userService = (UserService)    
    applicationContext.getBean("userService");
    userService.save();
    DataSource dataSource = (DataSource) 
    applicationContext.getBean("dataSource");
    Connection connection = dataSource.getConnection(); 
    System.out.println(connection);
    }

3. Spring integrates Junit

3.1 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");
 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 null pointer exceptions directly. So it can't be easily deleted.

3.2 Solutions to the above problems

Let Spring Junit be responsible for creating Spring containers, but you need to tell it the name of the configuration file

Test beans will need to be injected directly into test classes

3.3 Spring integration Junit step

1. Import spring to integrate Junit coordinates

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

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

(4) Injecting objects to be tested with @Autowire

(5) Create test methods for testing

3.4 Spring Integrated Junit Code Implementation

1. Import spring to integrate Junit coordinates

<!--It should be noted here that: spring5 Version requirements above junit The version must be 4.12 And above-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>5.0.2.RELEASE</version>
</dependency>
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
</dependency>

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

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

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

@RunWith(SpringJUnit4ClassRunner.class)
//Loading spring core configuration file
//@ContextConfiguration(value = {"classpath:applicationContext.xml"})
//Loading spring core configuration class
@ContextConfiguration(classes = {SpringConfiguration.class})
public class SpringJunitTest {
}

(4) Injecting objects to be tested with @Autowire

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {SpringConfiguration.class})
public class SpringJunitTest {
    @Autowired
    private UserService userService;
}

(5) Create test methods for testing

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {SpringConfiguration.class})public class SpringJunitTest {
    @Autowired
    private UserService userService;
    @Test
    public void testUserService(){
   	 userService.save();
    }
}

Spring integration Junit step

1. Import spring to integrate Junit coordinates

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

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

(4) Injecting objects to be tested with @Autowire

(5) Create test methods for testing

Keywords: Programming Spring JDBC MySQL Junit

Added by berridgeab on Thu, 15 Aug 2019 16:08:46 +0300