Spring系列之新註解配置+Spring集成junit+註解注入

Spring系列之註解配置

Spring是輕代碼而重配置的框架,配置比較繁重,影響開發效率,因此註解開發是一種趨勢,註解代替xml配置文件能夠簡化配置,提升開發效率
你原本要寫一段很長的代碼來構造一個Beam對象,可是若是使用註解的話只要使用一個註解符號便可
在這裏插入圖片描述java

下面咱們來說講一些常常使用的註解符號
@Component 使用類上用於實例化Bean
@Controller 使用web層類上用於實例化Bean
@Service 使用在Service層類上用於實例化service
@Repository 使用在dao層類上用於實例化Bean
@Autorwired 使用在字段上用於根據類型依賴注入
@Qualifier 結合結合@Autowired一塊兒使用根據名稱進行依賴注入
@Resource 至關於@Autowired+@Qualifier一塊兒使用
@Scope 標註bean的範圍
@PostConstruct 使用該在方法上標註該方法是Bean的初始化方法
@PostDestory 使用在方法上標註該方法是Bean的銷燬方法web

這三個沒有什麼區別,不過是爲了在後期讀代碼的時候更加利於咱們區分,好比看到@Controller就知道這是web層,看到@Service就知道這是service層spring

@Component  使用類上用於實例化Bean
@Controller    使用web層類上用於實例化Bean
@Service        使用在Service層類上用於實例化service
@Repository   使用在dao層類上用於實例化Bean

因此咱們只需講一個便可,其餘的使用方法均相同,這裏咱們使用@Component來說解
定義一個userDaolmp類sql

package com.pjh.dao;
import com.pjh.dao.Imp.userdao;
import org.springframework.stereotype.Component;
@Component("userDaoImp")
public class userDaoImp implements userdao {
    public void save() {
        System.out.println("save");
    }
}

定義一個測試類測試apache

@Test
    public void test(){
        ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
      userdao userDaoImp =(userdao) classPathXmlApplicationContext.getBean("userDaoImp");
      userDaoImp.save();
    }

而後咱們就發現了以下報錯
由藍色的劃線部分咱們能夠看出問題是:沒有一個名叫userDaoImp的bean
在這裏插入圖片描述
這是爲什呢?由於咱們雖然寫了註解,可是咱們要讓applicationContext.xml知道咱們使用了註解,要告訴他哪裏有個bean。因此咱們在applicationContext中還須要加入如下配置api

命名空間:xmlns:context="http://www.springframework.org/schema/context
約束路徑http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
註解的組件掃描:
<context:component-scan base-package="com.pjh"/>tomcat

成功運行
在這裏插入圖片描述app

接下來咱們再來說講如何使用註解進行注入

方式一:使用@Autowired+@Qualifier
目的:建立一個userdao類將其注入帶service類中框架

userdao類代碼maven

package com.pjh.dao;
import com.pjh.dao.Imp.userdao;
import org.springframework.stereotype.Component;
@Component("userDaoImp")
public class userDaoImp implements userdao {
    public void save() {
        System.out.println("save");
    }
}

service類代碼

package com.pjh.service.Imp;
import com.pjh.dao.Imp.userdao;
import com.pjh.dao.userDaoImp;
import com.pjh.service.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Repository;
import javax.annotation.Resource;
import javax.xml.bind.SchemaOutputResolver;

@Repository("serviceImp")
public class serviceImp implements service {
   @Autowired
   @Qualifier("userDaoImp")
   
   private userDaoImp userDaoImp;
    public void save() {
        System.out.println("sssssss");
       userDaoImp.save();
    }

}

測試類

@Test
    public void test(){
        ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
      service service =(service) classPathXmlApplicationContext.getBean("serviceImp");
      service.save();
    }

結果

在這裏插入圖片描述

方式二:使用@Resource()

就是把 @Autowired + @Qualifier("userDaoImp")換成@Resource(name="userDaoImp"),其他代碼均與方式一相同

package com.pjh.service.Imp;
import com.pjh.dao.Imp.userdao;
import com.pjh.dao.userDaoImp;
import com.pjh.service.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Repository;
import javax.annotation.Resource;
import javax.xml.bind.SchemaOutputResolver;
@Repository("serviceImp")
public class serviceImp implements service {
  /* @Autowired
   @Qualifier("userDaoImp")*/
    @Resource(name="userDaoImp")
   private userDaoImp userDaoImp;
    public void save() {
        System.out.println("sssssss");
       userDaoImp.save();
    }

}

結果

在這裏插入圖片描述
使人蛋碎的事情來了,報錯了,意思是不支持版本5
在這裏插入圖片描述
解決方案:
File->setting下設置項目的jdk版本
在這裏插入圖片描述

File->ProjectStruct下設置版本

在這裏插入圖片描述
結果

在這裏插入圖片描述
又報錯了,這。。。。。我tm心態崩了呀

在這裏插入圖片描述

根據報錯的內容是報了個空指針異常,這是爲何呢?爲何使用@Autowired + @Qualifier("userDaoImp")不報錯換成@Resource(name="userDaoImp")就報空指針呢

緣由:jdk版本不支持

解決方案:

1.更換本地的jdk版本,最好jdk1.8以上,jdk9不支持有bug
2.再maven.pom文件中引入以下依賴

<dependency>
        <groupId>org.apache.tomcat</groupId>
        <artifactId>tomcat-annotations-api</artifactId>
        <version>7.0.47</version>
    </dependency>

結果
成功運行
在這裏插入圖片描述終於解決完了
在這裏插入圖片描述
使用@Scope註解標註Bean的範圍
使用@Scope("prototype")

package com.pjh.dao;
import com.pjh.dao.Imp.userdao;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Component("userDaoImp")
@Scope("prototype")
public class userDaoImp implements userdao {
    public void save() {
        System.out.println("save");
    }
}

測試代碼

@Test
    public void test(){
        ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        userdao userdao =(userdao) classPathXmlApplicationContext.getBean("userDaoImp");
        userdao userdao1 =(userdao) classPathXmlApplicationContext.getBean("userDaoImp");
        System.out.println(userdao);
        System.out.println(userdao1);
    }

結果
在這裏插入圖片描述

使用@Scope("singleton")

package com.pjh.dao;
import com.pjh.dao.Imp.userdao;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Component("userDaoImp")
@Scope("singleton")
public class userDaoImp implements userdao {
    public void save() {
        System.out.println("save");
    }
}

結果

在這裏插入圖片描述
在這裏順便給你們複習複習singleton與prototype的區別吧
singleton
Bean的實例化個數:1個
Bean的實例化時機:當Spring核心配置文件被加載時
Bean的生命週期:
對象建立:當應用加載時對象建立
對象運行:只要容器在,對象就一直活着
對象銷燬:當應用卸載,容器銷燬時
prototype:在使用getBean方法的時候建立bean
prototype
Bean的實例化格式:多個
Bean的實例化時機:當調用getBean()方法時,實例化Bean
對象建立:當使用對象時,建立新的對象實例
對象運行:只要對象在使用中,對象就一直存在
對象銷燬:對象長時間不使用,就會被java的垃圾回收機制回收

初始化方法和銷燬方法

初始化方法
@PostConstract

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

銷燬方法
@PostDestroy

@PreDestroy
    public void  destroy(){
        System.out.println("在對象銷燬前執行");
    }

@Value()進行注入

package com.pjh.dao;
import com.pjh.dao.Imp.userdao;
import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
@Component("userDaoImp")
@Scope("singleton")
public class userDaoImp implements userdao {
    public void save() {
        System.out.println("save");
        System.out.println("讀取配置文件:"+one);
        System.out.println("普通類型:"+a);
    }
    @Value("${one.one}")
    private String one;
    @Value("4")
    private String a;

}

配置文件信息

one.one=1

applicationContext中添加的內容

<context:property-placeholder location="classpath*:one.properties"/>

測試代碼

@Test
    public void test(){
        ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        userdao userdao =(userdao) classPathXmlApplicationContext.getBean("userDaoImp");
        userdao.save();
    }

結果

在這裏插入圖片描述
使用上面的註解還不能夠所有替代xml配置文件,還須要使用註解替代的配置以下
非自定義的Bean的配置:
加載properties文件的配置:<context:property-placeholder>
註解掃描的配置: context:component-scan
引入其餘文件:

Spring新註解

@Configuration 用於指定當前類是一個Spring配置類,建立容器時會從該類上加載註解,該類不能是匿名類與final類
@ComponentScan 用於指定Spring在初始化容器的時候要掃描包
做用與Spring中的此代碼相同:context:component-scan
@Bean 使用方法,將該方法的返回值返回到容器中
@Import 用於導入其餘配置類
@PropertySource 用於加載properties文件中的配置

案例

核心配置類

package com.pjh.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.stereotype.Component;
/*標誌該類是核心配置類*/
@Configuration
/*掃描包*/
@Component("com/pjh")
/*導入其餘配置類*/
@Import(DataSourceConfig.class)
public class Springconfig {
}

副配置類

package com.pjh.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 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;
    /*Spring會將當前方法的返回值以指定名稱存儲到Spring容器中*/
    @Bean("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
    public void test() throws SQLException {
        ApplicationContext applicationContext = new
                AnnotationConfigApplicationContext(Springconfig.class);
      DataSource bean = (DataSource)applicationContext.getBean("dataSource");
        Connection connection = bean.getConnection();
        System.out.println(connection);
    }

結果
成功建立connection鏈接
在這裏插入圖片描述

Spring集成junit

爲何使用Spring集成junit?
在測試類中每一個類都要寫下面的兩行代碼

ApplicationContext applicationContext = new
                AnnotationConfigApplicationContext(Springconfig.class);
      DataSource bean = (DataSource)applicationContext.getBean("dataSource");

這兩行代碼的做用是獲取容器,不寫的話報空指針異常
爲了讓咱們測試的時候不用進行反覆的寫上述兩行的操做,咱們使用Spring來集成junit,用springjunit來建立spring容器,
咱們只需將配置文件的名稱告訴他們便可,將須要的bean直接在容器中進行注入

Spring集成junit的步驟

須要導入的jar包

<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.13</version>
        <scope>test</scope>
    </dependency>

這是我spring系列的學習文章,我也會不斷的學習,文章若有錯誤還請批評指正,若有幫助你們能夠點點關注,咱們一同窗習

在這裏插入圖片描述

相關文章
相關標籤/搜索