Spring配置數據源和注解開發


Spring配置數據源

數據源(連接池)的作用

數據源(連接池)是提高程序性能如出現的
事先實例化數據源,初始化部分連接資源
使用連接資源時從數據源中獲取
使用完畢后將連接資源歸還給數據源
常見的數據源(連接池):DBCP、C3P0、BoneCP、Druid等

 

開發步驟

①導入數據源的坐標和數據庫驅動坐標
②創建數據源對象
③設置數據源的基本連接數據
④使用數據源獲取連接資源和歸還連接資源

 

 

 

現在spring項目中的pom中導入jar包坐標

<!--  導入第三方jar包-->
    <dependencies>
<!--        導入Spring的jar 包-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.0.3.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <!--導入數據源連接需要的jar包-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.32</version>
        </dependency>
        <dependency>
            <groupId>c3p0</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.1.2</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.0.9</version>
        </dependency>
    </dependencies>
第三方jar包坐標導入

 

 

手動創建c3p0的數據源

    @Test
    //手動創建c3p0的數據源
    public void testTwo() throws Exception {
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setDriverClass("com.mysql.jdbc.Driver");
        dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/book");
        dataSource.setUser("zhao");
        dataSource.setPassword("123456");
        Connection conn = dataSource.getConnection();
        System.out.println(conn);
        conn.close();

    }
手動創建c3p0的數據源

 

手動創建Driver數據源

    @Test
    //手動創建Driver數據源
    public void TestOne() throws Exception{
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/book");
        dataSource.setUsername("zhao");
        dataSource.setPassword("123456");
        Connection conn = dataSource.getConnection();
        System.out.println(conn);
        conn.close();
    }
手動創建Driver數據源

 

 

提取數據庫信息放到配置文件中讀取

上面都是我們手動創建然后配置信息都在java源代碼中這樣會導致以后如果修改數據庫的鏈接信息不方便

后期更改數據庫的要找到源碼修改太麻煩

 

提取jdbc.properties配置文件

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/book
jdbc.username=zhao
jdbc.password=123456

在設置properties的時候,里面的內容不可以加上分號

 

讀取jdbc.properties配置文件創建連接池

 

 //讀取jdbc.properties配置文件創建連接池
    @Test
    public void TestThree() throws Exception {
        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 conn = dataSource.getConnection();
        System.out.println(conn);
    }

 

上面都不是Spring的 容器來配置數據源的

下面我們使用spring容器創建數據源

Spring配置數據源

可以將DataSource的創建權交由Spring容器去完成
DataSource有無參構造方法,而Spring默認就是通過無參構造方法實例化對象的
DataSource要想使用需要通過set方法設置數據庫連接信息,而Spring可以通過set方法進行字符串注入

applicationContext.xml

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

 

測試從容器當中獲取數據源

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

 

 

上面的方法是沒有抽取jdbc的配置文件,我們將配置文件抽取到properties文件中

將數據源的配置抽取到properties中,抽取到xml解析比較費勁,properties是鍵值對的方式,

Spring容器提取配置文件到Properties中然后

抽取jdbc配置文件

applicationContext.xml加載jdbc.properties配置文件獲得連接信息。
首先,需要引入context命名空間和約束路徑:

命名空間首先要在applicaltionContext.xml中創建

需要引入context命名空間和約束路徑:
命名空間:xmlns:context="http://www.springframework.org/schema/context"
約束路徑:http://www.springframework.org/schema/context 
http://www.springframework.org/schema/context/spring-context.xsd

命名空間的創建在beans中的xmlns中復制第一個的xmlns人然后改成xmlns:context

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

    <context:property-placeholder location="classpath:jdbc.properties"/>  <!--加載jdbc的配置文件-->
<!--    <bean id="datasource" class="com.mchange.v2.c3p0.ComboPooledDataSource">   這里是使用cp30-->
    <bean id="datasource" class="com.alibaba.druid.pool.DruidDataSource"><!--這是使用druid數據源連接-->
        <property name="driverClassName" value="${jdbc.driver}"/>  <!--這里指定的name值是你的讀取jdbc.properties配置文件方法中的set后面的內容-->
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>


</beans>

 

 

jdbc.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/book
jdbc.username=zhao
jdbc.password=123456

 

 

Spring容器加載properties文件

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

 

實現:

    //Spring容器創建Druid的數據源
    @Test
    public void TestFive() throws SQLException {
        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
        DataSource bean = app.getBean(DataSource.class);
        Connection connection = bean.getConnection();
        System.out.println(connection);
    }

 

Spring注解開發

 

spring的注解分為原始注解和新注解

Spring原始注解:

Spring是輕代碼重配置的框架,配置比較繁重,影響開發效率,所以注解開發是一種趨勢,注解代替Xml配置文件可以簡化配置,提高開發效率

 

Spring原始注解主要是替代的配置

 

注解 說明
@Component 使用在類上用於實例化Bean
@Controller 使用在web層類上用於實例化Bean
@Service 使用在Service層類上用於實例化Bean
@Repository 使用在dao層類上用於實例化Bean
@Autowired 使用在字段上用於根據類型依賴注入
@Qualifier 結合@Autowired一起使用用於根據名稱進行依賴注入
@Resource 相當於@Autowired+@Qualifier,按照名稱進行注入
@Value 注入普通屬性
@Scope  標注Bean的作用范圍
@PostConstruct 使用在方法上標注該方法是Bean的初始化方法
@PreDestroy 使用在方法上標注該方法是Bean的銷毀方法

 

注意:

  使用注解進行開發時,需要在applicationContext.xml中配置組件掃描,作用是指定哪個包及其子包下的Bean需要

進行掃描以便識別使用注解配置的類、字段和方法。

 

首先我們對比下Spring的依賴注入使用注解和不使用注解的方法

 

Spring的依賴注入

在創建完UserServiceImpl.java和UserDaoImpl.java之后我們要在配置文件applicationContext.xml中進行對應的Bean對象的創建和注入

 

UserDaoImpl.java

public class UserDaoImpl implements UserDao {
    public void save() {
        System.out.println("come on Running....");
    }
}

 

UserServiceImpl.java

public class UserServiceImpl implements UserService {

    private UserDao userDao;

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

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

 

applicationContext.xml

    <bean id="userDao" class="com.spring.Dao.Impl.UserDaoImpl"></bean>  <!--創建UserDaoImpl的Bean對象-->
    <bean id="userService" class="com.spring.service.Impl.UserServiceImpl"><!--創建UserServiceImpl的Bean對象-->
        <property name="userDao" ref="userDao"/><!--將UserDaoImpl的bean對象注入到UserService中-->
    </bean>

 

這樣配置起來是很麻煩的

 

Spring的注解注入

我們可以將Spring的要在applicationContext.xml中配置的內容全部都通過注解來解決

 

@Component 實例化bean對象

UserDaoImpl.java

 

 

@Component("userDao")  //實例化bean對象,並且這個bean對象的id是userDao
// 相當於在applicationContext.xml中配置這個<bean id="userDao" class="com.spring.Dao.Impl.UserDaoImpl"></bean>  <!--創建UserDaoImpl的Bean對象-->
public class UserDaoImpl implements UserDao {
    public void save() {
        System.out.println("come on Running....");
    }
}

 

 

userServiceImpl.java

@Component("userService") // 實例化Bean對象,這個bean對象的id是userService
public class UserServiceImpl implements UserService {
    @Autowired  // 類型注入 將這個參數注入到此處
    @Qualifier("userDao") // 依賴注入,注入userDao這個bean這個是寫你的要注入你的bean的id  你要注入userDaoImpl的bean  它的id是userDao
    private UserDao userDao;

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

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

 

如果只配置了上面的注解,沒有聲明注解的作用的范圍也是不可以使用的

Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@23ab930d: startup date [Tue Dec 15 15:42:08 CST 2020]; root of context hierarchy
十二月 15, 2020 3:42:08 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions

 

上面的報錯就是未配置注解掃描

配置注解掃描要在applicationContext.xml中配置

 

 

<!-- 配置注解掃描-->
    <context:component-scan base-package="com.spring"></context:component-scan>

 

所以我們在applicationContext.xml的配置文件中設置這個 所以即使不在我們也要創建一個配置文件

 

 

 

 因為我們在運行的時候也會通過這個配置文件運行的

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

 

 

使用@Component或@Repository標識UserDaoImpl需要Spring進行實例化。

//@Component("userDao")  //實例化bean對象,並且這個bean對象的id是userDao
@Repository("userDao") // 使用作用的dao上的bean實例化注解

// 相當於在applicationContext.xml中配置這個<bean id="userDao" class="com.spring.Dao.Impl.UserDaoImpl"></bean>  <!--創建UserDaoImpl的Bean對象-->
public class UserDaoImpl implements UserDao {
    public void save() {
        System.out.println("come on Running....");
    }
}

 

其實我們在使用注解的@Component @Repository @Service @ Controller 這些注解作用都一樣只不過是作用在不同的區域更規范,如果不規范也是可以互相使用的

 

Bean的依賴注入

如果我們要進行bena的依賴注入 可以使用

使用@Autowired或者@Autowired+@Qulifier或者@Resource進行userDao的注入

@Repository("userService")
public class UserServiceImpl implements UserService {
//    @Autowired  // 類型注入 將這個參數注入到此處
//    @Qualifier("userDao") // 依賴注入,注入userDao這個bean這個是寫你的要注入你的bean的id  你要注入userDaoImpl的bean  它的id是userDao
    @Resource(name = "userDao")
    private UserDao userDao;
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
    public void save() {
        userDao.save();
    }
}

 

 使用@Value進行字符串的注入

    @Value("laowang")  // value進行普通賦值
    private String name;

 

使用@Scope標注Bean的范圍

    

//@Scope("prototype")
@Scope("singleton")
public class UserDaoImpl implements UserDao {
  //此處省略代碼
}

 

使用@PostConstruct標注初始化方法,使用@PreDestroy標注銷毀方法

 

@PostConstruct
public void init(){
    System.out.println("初始化方法....");
}

@PreDestroy
public void destroy(){
    System.out.println("銷毀方法.....");
}

 

 Spring新注解

 

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

非自定義的Bean的配置:
加載properties文件的配置:context:property-placeholder
組件掃描的配置:context:component-scan

引入其他文件:

注解 說明
@Configuration  用於指定當前類是一個 Spring 配置類,當創建容器時會從該類上加載注解
@ComponentScan

用於指定 Spring 在初始化容器時要掃描的包。 作用和在 Spring 的 xml 配置文件中
的 <context:component-scan base-package="com.itheima"/>一樣

@Bean 使用在方法上,標注將該方法的返回值存儲到 Spring 容器中
@PropertySource 用於加載.properties 文件中的配置
@Import 用於導入其他配置類

 

 

@Configuration 指定當前類是spring的核心配置文件

@ ComponentScan("組件的名稱") // 組件掃描 

@Bean("dataSource") // Spring會將當前方法的返回值以指定名稱存儲到Spring容器中

@Import({類})

 

@Configuration  //指定當前類是spring的核心配置文件
@ComponentScan("com.spring") // 組件掃描  相當於    <context:component-scan base-package="com.spring"></context:component-scan>
@PropertySource("classpath:jdbc.properties")  // 加載配置文件  <context:property-placeholder location="classpath:jdbc.properties"/>
public class SpringConfiguration {

    @Bean("dataSource") // Spring會將當前方法的返回值以指定名稱存儲到Spring容器中
    public DataSource getDataSource() throws PropertyVetoException {
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setDriverClass("com.mysql.jdbc.Driver");
        dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/book");
        dataSource.setUser("zhao");
        dataSource.setPassword("123456");
        return dataSource;
    }
}

 

 

eg:

spring的核心配置類

SpringConfiguration.java

@Configuration  //指定當前類是spring的核心配置文件
@ComponentScan("com.spring") // 組件掃描  相當於    <context:component-scan base-package="com.spring"></context:component-scan>
@Import(DataSourceConfiguration.class)  // 將DataourceConfigureation類加載到當前類中
public class SpringConfiguration {
    
}


DataSourceConfiguration.java
@PropertySource("classpath:jdbc.properties")  // 加載配置文件  <context:property-placeholder location="classpath:jdbc.properties"/>
public class DataSourceConfiguration {
    // @value進行字符串值的注入 對配置文件的值進行賦值
    @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將此方法放到speing容器后后面可以直接使用getBean然后獲取方法名
    @Bean("dSource") // Spring會將當前方法的返回值以指定名稱存儲到Spring容器中
    public DataSource getDataSource() throws PropertyVetoException {
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setDriverClass(driver);
        dataSource.setJdbcUrl(url);
        dataSource.setUser(username);
        dataSource.setPassword(password);
        return dataSource;
    }
}

 

 

main

    public static void main(String[] args) throws SQLException {
//        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
        ApplicationContext app = new AnnotationConfigApplicationContext(SpringConfiguration.class); //獲取核心配置類
        UserService bean = app.getBean(UserService.class);
        bean.save();
        DataSource dataSource = (DataSource) app.getBean("dSource");  // 獲取@Bean注解生成的spring容器內的方法
        Connection connection = dataSource.getConnection();
        System.out.println(connection);
    }

 

 

上面使用這種新注解的方式就徹底放棄了xml配置文件了 

 

 

 

Spring整合Junit

1 原始Junit測試Spring的問題

在測試類中,每個測試方法都有以下兩行代

ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
IAccountService as = ac.getBean("accountService",IAccountService.class);

 

這兩行代碼的作用是獲取容器,如果不寫的話,直接會提示空指針異常。所以又不能輕易刪掉。

上述問題解決思路

讓SpringJunit負責創建Spring容器,但是需要將配置文件的名稱告訴它
將需要進行測試Bean直接在測試類中進行注入

 

Spring集成Junit步驟

①導入spring集成Junit的坐標
②使用@Runwith注解替換原來的運行期
③使用@ContextConfiguration指定配置文件或配置類
④使用@Autowired注入需要測試的對象
⑤創建測試方法進行測試

 Spring集成Junit代碼實現

 

1: ①導入spring集成Junit的坐標

<!--此處需要注意的是,spring5 及以上版本要求 junit 的版本必須是 4.12 及以上-->
    <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>

 

②使用@Runwith注解替換原來的運行期

使用@Runwith注解替換原來的運行期

@RunWith(SpringJUnit4ClassRunner.class) // 測試
//@ContextConfiguration("classpath:applicationContext.xml") //告訴它測試的文件是哪個
@ContextConfiguration(classes = {SpringConfiguration.class}) // 測試核心配置類
public class springTest {
    @Autowired  // 注入要測試的 對象
    private UserService userService;

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

}

 

 ③使用@ContextConfiguration指定配置文件或配置類

@RunWith(SpringJUnit4ClassRunner.class) // 測試
//@ContextConfiguration("classpath:applicationContext.xml") //加載spring核心配置文件
@ContextConfiguration(classes = {SpringConfiguration.class}) // 加載測試核心配置類
public class springTest {
    @Autowired  // 注入要測試的 對象
    private UserService userService;

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

}

 

④使用@Autowired注入需要測試的對象

    @Autowired  // 注入要測試的 對象
    private UserService userService;

 

⑤創建測試方法進行測試

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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM