Java之Spring入门到精通【IDEA版】IoC和DI注解开发(二)(一篇文章精通系列)

x33g5p2x  于10个月前 转载在 Java  
字(18.7k)|赞(0)|评价(0)|浏览(124)

上一篇文章地址:Java之Spring入门到精通【IDEA版】Spring的IoC和DI(一)(一篇文章精通系列)

一、Spring配置数据源

1、数据源(连接池)

1)数据源(连接池)的作用
  • 数据源(连接池)是提高程序性能如出现的
  • 事先实例化数据源,初始化部分连接资源
  • 使用连接资源时从数据源中获取
  • 使用完毕后将连接资源归还给数据源

常见的数据源(连接池):DBCP、C3P0、BoneCP、Druid等

2)数据源的开发步骤
  • 导入数据源的坐标和数据库驱动坐标
  • 创建数据源对象
  • 设置数据源的基本连接数据
  • 使用数据源获取连接资源和归还连接资源

2、数据源的手动创建(Java代码实现)

(1)创建新的项目

(2)导入c3p0和druid的,mysql数据库驱动坐标

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.itbluebox</groupId>
    <artifactId>Spring-DB</artifactId>
    <version>1.0.0-SNAPSHOT</version>

    <properties>
        <spring.version>5.0.5.RELEASE</spring.version>
    </properties>

    <dependencies>
        <!--导入spring的context坐标,context依赖core、beans、expression-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!-- C3P0连接池 -->
        <dependency>
            <groupId>c3p0</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.1.2</version>
        </dependency>
        <!-- Druid连接池 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.10</version>
        </dependency>
        <!-- mysql驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.39</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

    </dependencies>

</project>
(3)创建test数据库
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for `book`
-- ----------------------------
DROP TABLE IF EXISTS `book`;
CREATE TABLE `book` (
  `id` int(15) NOT NULL AUTO_INCREMENT,
  `title` varchar(20) NOT NULL,
  `auth` varchar(20) DEFAULT NULL,
  `price` float(20,2) DEFAULT NULL,
  `cbs` varchar(20) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of book
-- ----------------------------
INSERT INTO `book` VALUES ('1', 'Java从入门到精通', '张三', '15.00', '清华大学');
INSERT INTO `book` VALUES ('5', '11', '11', '11.00', '11');
INSERT INTO `book` VALUES ('6', '11', '11', '11.00', '11');
INSERT INTO `book` VALUES ('8', 'JavaScript入门', '刘伟', '55.60', '哈哈');
INSERT INTO `book` VALUES ('10', 'MySQL从入门到精通', '刘玉徐', '85.00', '???');
-- ----------------------------
-- Table structure for `user`
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `uname` varchar(255) NOT NULL,
  `upass` varchar(255) DEFAULT NULL,
  `tel` varchar(255) NOT NULL,
  `address` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=124 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES ('123', '123', '123', '123', '123');
(4)创建C3P0连接池

package com.itbluebox.db;

import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.junit.Test;
import java.sql.Connection;

public class TestC3P0 {
    @Test
    public void testC3P0() throws Exception{
        //数据源
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        //设置数据库连接参数
        dataSource.setDriverClass("com.mysql.jdbc.Driver");
        dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test");
        dataSource.setUser("root");
        dataSource.setPassword("root");
        //获得连接对象
        Connection connection = dataSource.getConnection();
        System.out.println(connection);
    }
}

运行测试

运行成功

(5)创建Druid连接池

package com.itbluebox.db;

        import com.alibaba.druid.pool.DruidDataSource;
        import com.alibaba.druid.pool.DruidPooledConnection;
        import org.junit.Test;

public class TestDruid {
    @Test
    public void testDruid() throws Exception{
        //创建数据库源
        DruidDataSource dataSource = new DruidDataSource();
        //设置数据库连接参数
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/test");
        dataSource.setUsername("root");
        dataSource.setPassword("root");
        //获取连接对象
        DruidPooledConnection connection = dataSource.getConnection();
        System.out.println(connection);
    }
}

运行成功

3、数据源的手动创建(读取jdbc.properties)

(1)提取jdbc.properties配置文件

jdbc.driver = com.mysql.jdbc.Driver
jdbc.url = jdbc:mysql://localhost:3306/test
jdbc.username = root
jdbc.password = root
(2)读取jdbc.properties配置文件创建连接池

package com.itbluebox.db;

import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.junit.Test;

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

public class TestC3P0ByProperties {

    @Test
    public void C3P0ByProperties() throws Exception{

        //加载类路径下的jdbc.properties
        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);

    }

}

4、测试从容器当中获取数据源(applicationContext.xml)

(1)创建applicationContext.xml

<?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:p="http://www.springframework.org/schema/p" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd" >

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

</beans>
(2)创建测试类,测试从容器当中获取数据源

package com.itbluebox.db;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import javax.sql.DataSource;
import java.sql.Connection;
public class TestC3P0Application {
    @Test
    public void TestC3PO() throws  Exception{

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

5、抽取jdbc配置文件

(1)修改applicationContext.xml

applicationContext.xml加载jdbc.properties配置文件获得连接信息。
*
首先,需要引入context命名空间和约束路径:
*
命名空间:xmlns:context="http://www.springframework.org/schema/context"
*
约束路径:

http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
  • Spring容器加载properties文件
<context:property-placeholder location="xx.properties"/>
<property name="" value="${key}"/>

<?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:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd" >
    <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 name="jdbcUrl" value="${jdbc.url}"/>
        <property name="user" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>
</beans>

运行测试

二、Spring注解开发

1、Spring原始注解

Spring是轻代码而重配置的框架,配置比较繁重,影响开发效率,所以注解开发是一种趋势,注解代替xml配置文件可以简化配置,提高开发效率。

  • Spring原始注解主要是替代<Bean>的配置

注意:

使用注解进行开发时,需要在applicationContext.xml中配置组件扫描,

作用是指定哪个包及其子包下的Bean

(1)需要进行扫描以便识别使用注解配置的类、字段和方法。
<!--注解的组件扫描-->
<context:component-scan base-package="com.itbluebox">
</context:component-scan>

在这里我们切换回第一篇文章创建的工程Spring-test-demo

<?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:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd" >
    <context:component-scan base-package="com.itbluebox"> </context:component-scan>

</beans>
(2)UserDao:使用@Compont或@Repository标识UserDaoImpl需要Spring进行实例化。

package com.itbluebox.dao.impl;

import com.itbluebox.dao.UserDao;
import org.springframework.stereotype.Component;

@Component("userDao")
public class UserDaoImpl implements UserDao {

    public void save() {
        System.out.println("UserDao save method running....");
    }

}
(3)UserServiceImpl

使用@Compont或@Service标识UserServiceImpl需要Spring进行实例化
使用@Autowired或者@Autowired+@Qulifier或者@Resource进行userDao的注入

package com.itbluebox.service.impl;
import com.itbluebox.dao.UserDao;
import com.itbluebox.service.UserService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

@Service("userService")
public class UserServiceImpl implements UserService {

    /* @Autowired @Qualifier("userDao") */
    @Resource(name="userDao")
    private UserDao userDao;

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    public void save() {
        System.out.println("UserServiceImpl save method running....");
        userDao.save();

    }
}
(4)创建UserController

package com.itbluebox.web;

import com.itbluebox.service.UserService;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class UserController {

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

运行测试

(5)使用@Value进行字符串的注入
  • 引入依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.itbluebox</groupId>
    <artifactId>spring-test-demo</artifactId>
    <version>1.0.0-SNAPSHOT</version>


    <properties>
        <spring.version>5.0.5.RELEASE</spring.version>
    </properties>

    <dependencies>
        <!--导入spring的context坐标,context依赖core、beans、expression-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!-- C3P0连接池 -->
        <dependency>
            <groupId>c3p0</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.1.2</version>
        </dependency>
        <!-- Druid连接池 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.10</version>
        </dependency>
        <!-- mysql驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.39</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

    </dependencies>

</project>
  • 创建jdbc.properties

  • 完善applicationContext.xml配置文件

<?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:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd" >
    <context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>

    <!--注解的组件扫描-->
    <context:component-scan base-package="com.itbluebox"></context:component-scan>

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

</beans>
  • 完善UserDaoImpl

package com.itbluebox.dao.impl;

import com.itbluebox.dao.UserDao;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component("userDao")
public class UserDaoImpl implements UserDao {

    @Value("注入普通数据")
    private String str;

    @Value("${jdbc.driver}")
    private String driver;

    public void save() {
        System.out.println(str);
        System.out.println(driver);
        System.out.println("UserDao save method running....");
    }

}
  • 运行测试

(6)使用@Scope标注Bean的范围
@Scope("singleton")

(7)使用@PostConstruct标注初始化方法,使用@PreDestroy标注销毁方法

完善UserServiceImpl

package com.itbluebox.service.impl;
import com.itbluebox.dao.UserDao;
import com.itbluebox.service.UserService;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

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

@Service("userService")
@Scope("singleton")
public class UserServiceImpl implements UserService {
    /* @Autowired @Qualifier("userDao") */
    @Resource(name="userDao")
    private UserDao userDao;
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
    public void save() {
        System.out.println("UserServiceImpl save method running....");
        userDao.save();
    }
    @PostConstruct
    public void init(){
        System.out.println("初始化方法。。。。");
    }
    @PreDestroy
    public void destroy(){
        System.out.println("销毁方法。。。。");
    }

}
  • 完善UserController,添加app.close()

package com.itbluebox.web;

import com.itbluebox.service.UserService;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class UserController {

    public static void main(String[] args) {
        ClassPathXmlApplicationContext app =
                new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService = app.getBean(UserService.class);
        userService.save();
        app.close();
    }
}
  • 运行测试

3、Spring新注解

使用上面的注解还不能全部替代xml配置文件,还需要使用注解替代的配置如下:

非自定义的Bean的配置:<bean>
加载properties文件的配置:<context:property-placeholder>
组件扫描的配置:<context:component-scan>
引入其他文件:<import>

(1)创DataSourceConfiguration

package com.itbluebox.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;

@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(name = "dataSource")
    private DataSource getDataSource() throws PropertyVetoException{
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setDriverClass(driver);
        dataSource.setJdbcUrl(url);
        dataSource.setUser(username);
        dataSource.setPassword(password);
        return dataSource;
    }

}
(2)创建SpringConfiguration

@Configuration
@ComponentScan
@Import

package com.itbluebox.config;

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

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

删除applicationContext.xml当中dataSource相关配置

创建TestAnnoConfig

package com.itbluebox.web;

import com.itbluebox.service.UserService;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class UserController {

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

运行测试

三、Spring集成Junit

1、原始Junit测试Spring的问题

在测试类中,每个测试方法都有以下两行代码:

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

IAccountService as = ac.getBean("accountService",IAccountService.class);

这两行代码的作用是获取容器,如果不写的话,直接会提示空指针异常。所以又不能轻易删掉。

2、上述问题解决思路

让SpringJunit负责创建Spring容器,但是需要将配置文件的名称告诉它
将需要进行测试Bean直接在测试类中进行注入

3、Spring集成Junit步骤

  • 导入spring集成Junit的坐标
  • 使用@Runwith注解替换原来的运行期
  • 使用@ContextConfiguration指定配置文件或配置类
  • 使用@Autowired注入需要测试的对象
  • 创建测试方法进行测试

4、Spring集成Junit代码实现

(1)导入spring集成Junit的坐标

<dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
(2)创建SpringJunitTest

使用@Runwith注解替换原来的运行期,使用
@ContextConfiguration指定配置文件或配置类
使用@Autowired注入需要测试的对象
创建测试方法进行测试

package com.itbluebox;

import com.itbluebox.config.SpringConfiguration;
import com.itbluebox.domain.User;
import com.itbluebox.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;
@RunWith(SpringJUnit4ClassRunner.class)
//加载spring核心配置文件
//@ContextConfiguration(value = {"classpath:applicationContext.xml"})
//加载spring核心配置类
@ContextConfiguration(classes = {SpringConfiguration.class})
public class SpringJunitTest {

    @Autowired
    private UserService userService;

    @Test
    public void test() {
        userService.save();
    }
}

运行成功

5、知识要点

Spring集成Junit步骤

导入spring集成Junit的坐标
使用@Runwith注解替换原来的运行期
使用@ContextConfiguration指定配置文件或配置类
使用@Autowired注入需要测试的对象
创建测试方法进行测试

相关文章

热门文章

更多