Spring基於註解的IOC配置總結


Spring基於Xml的IoC配置總結——SpringIOC容器,IOC中bean標籤詳解,Spring依賴注入


常用註解詳解

1.用於創建對象的註解

@Controller:一般用於表現層的註解。
@Service:一般用於業務層的註解。
@Repository:一般用於持久層的註解。
@Component:所有類都可用。

作用:

相當於在xml中配置一個bean,創建一個對象的實例,並存入SpringIOC容器中,給SpringIOC容器管理。

示例:
@Service(value = "userService")//默認value值是userServiceImpl 
//value屬性:相當於xml配置中指定bean的id,如果不指定value屬性,默認是當前類首字母小寫的類名。  可以理解爲在容器中要通過該標識才能找到該對象
public class UserServiceImpl implements UserService {
    public void add(User user) {
        userDao.add(user);
    }
}
理解:
//註解
@Service(value = "userService")
//相當於xml配置文件配置了一個bean
<bean id="userService" class="com.mycode.service.impl.UserServiceImpl" />
//相當於java代碼
UserService userService= new com.mycode.service.impl.UserServiceImpl();


2.用於注入數據的註解(實現依賴注入)

  • 理解
//用於注入數據的註解
//相當於xml配置文件配置
<property name="" ref=""><property name="" value="">
@Autowired
  • 作用:默認自動按照類型注入,當使用註解注入屬性時,set方法可以省略(用xml配置需要該類提供set方法),只能注入其他bean類型。
  • 注意: 當有多個類型匹配時,使用時要使用@Qualifier(value = "創建對象的註解的屬性value值") 指定當前屬性需要注入的對象的名字,在spring容器查找,找到了則注入成功,找不到則報錯。
@Repository(value = "userDao1")
public class UserDao1Impl implements UserDao {

}

@Repository(value = "userDao2")
public class UserDao2Impl implements UserDao {

}

public class UserServiceImpl implements UserService {
    @Autowired
    @Qualifier(value = "userDao1")
    /*@Qualifier: 和@Autowired一起結合使用,在屬性上不能單獨使用,
    指定當前屬性需要注入的對象的名字(創建對象的註解的屬性value值,即(相當於)也是xml配置的bean的id值)*/
    private UserDao userDao;
 }


如果像這樣有多個類型可以匹配,又不用@Qualifier指定注入那個類型,則報錯:
No qualifying bean of type 'com.mycode.dao.UserDao' available: expected single matching bean but found 2: userDao2,userDao1
  • 注入方式:默認根據類型注入,即找UserService 的實現類的Bean對象,將Bean對象賦值給該屬性;如果根據類型注入方式注入失敗,則根據名字(即創建對象的註解的屬性value值)注入。

@Qualifier

  • 作用: 在自動按照類型注入的基礎之上,再按照Bean的id注入。在給字段(屬性)注入時不能獨立使用,必須和@Autowire一起使用;給方法參數注入時,可以獨立使用。

@Resource
  • 作用:默認根據 創建對象的註解的value值(即也相當於xml配置Bean的id值)注入,只能注入其他bean類型。
  • 示例
public class UserServiceImpl implements UserService {
    //直接按照bean的id注入
    @Resource(name = "userDao2")
    private UserDao userDao;
 }
  • 注入方式:默認根據名字注入,如果根據名字注入方式失敗,則根據類型注入。

@Value
  • 作用:注入基本數據類型和String類型數據, 一般用於注入配置文件中的數據,如jdbc的配置文件。(參考:spring純註解配置,使用配置類,替換xml配置)


3.用於改變Bean作用範圍的註解:

@Scope: 指定bean的作用範圍。

  • 示例
@Scope(value = "singleton")
//value屬性:指定對象的作用範圍  singleton(單例) prototype(多例) request(一次請求) session(一次會話) globalsession
public class UserServiceImpl implements UserService {
}
  • 理解
//用於改變Bean作用範圍的註解
//相當於xml配置文件配置
<bean id="" class="" scope="">

4.與Bean生命週期相關的註解

@PostConstruct:指定類中的初始化方法名稱,對象創建之後,調用該方法。

@PreDestroy:指定類中銷燬方法名稱,容器銷燬之前調用該方法。

  • 注意:加入註解,要寫對應的方法。
  • 理解
//與Bean生命週期相關的註解
//相當於xml配置文件配置
<bean id="" class="" init-method="對象創建之後調用的方法 方法名" destroy-method="對象銷燬之前調用的方法 方法名" />

xml配置和註解組合使用注意事項

基於以上註解,xml配置和註解組合使用時,則需要在xml配置中加入以下配置

    <!-- 配置spring創建容器時要掃描的包,掃描指定包的註解-
			以下配值爲掃描com.mycode下的所有包
	->
    <context:component-scan base-package="com.mycode" />

這樣類中的註解纔會有效,像在UserServiceImpl類使用創建對象的註解,而在配置文件中並無做以上配置,則在使用Spring容器獲取該類實例化對象時報錯:

信息: Loading XML bean definitions from class path resource [beans.xml]
NoSuchBeanDefinitionException: No bean named 'userServiceImpl' available

Spring純註解配置,使用配置類,替換xml配置

Spring集成DBUtils,基於xml配置的ioc實現業務層和持久層解耦中的xml配置文件,使用配置類替換xml配置來學習其他幾個註解

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

    <!--配置spring創建容器時要掃描的包,掃描指定包的註解 -->
    <context:component-scan base-package="com.mycode" />

    <!--創建QueryRunner對象   -->
    <bean id="queryRunner" class="org.apache.commons.dbutils.QueryRunner">
        <!--使用類中的public QueryRunner(DataSource ds)構造函數給成員變量賦值 根據構造函數中參數的名字注入-->
        <constructor-arg name="ds" ref="datasource"/>
    </bean>

    <!--創建數據源   DruidDataSource-->
    <bean id="datasource" class="com.alibaba.druid.pool.DruidDataSource">
        <!--調用類中的set方法實現注入功能  DruidDataSource類中提供了需要注入成員的set方法-->
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql:///spring" />
        <property name="username" value="root" />
        <property name="password" value="1998" />
    </bean>
    
</beans>

@Configuration:用於指定當前類是一個spring配置類(spring的配置類,相當於xml配置文件),當創建容器時會從該類上加載註解。

@ComponentScan: 用於指定spring在初始化容器時要掃描的包。

@Bean:寫在方法上,表明使用此方法創建一個對象,並且放入spring容器。

@PropertySource: 用於加載.properties文件中的配置。

@Import:用於導入其他配置類,則被引入的配置類可以不用寫@Configuration註解。 value屬性:指定其他配置類的字節碼。

  • 示例(spring配置類)
@Configuration
/*@Configuration :用於指定當前類是一個spring配置類(相當於xml配置文件) */

@ComponentScan(value = {"com.mycode"})
/*@ComponentScan :用於指定spring在初始化容器時要掃描的包。
相當於xml配置文件中的:<context:component-scan base-package="com.mycode"/>
*/

@PropertySource(value = "classpath:druid.properties")
/*@PropertySource: 用於加載.properties文件中的配置。
(解決硬編碼問題)配置數據源時,可以把連接數據庫的信息寫到properties配置文件中,使用此註解指定properties配置文件的位置。
如properties配置文件在類路徑下,需要加上上classpath:
 */
public class SpringConfig {

    @Value("${url}")
    /*@Value:注入字符串和基本數據類型

    */
    private String url;
    @Value("${myusername}")
    private String username;
    @Value("${password}")
    private String password;
    @Value("${driverClassName}")
    private String driverClassName;


    //創建QueryRunner對象
    @Bean
    /*  @Bean:使用此方法創建一個對象,將創建的對象(返回值)交給Spring容器管理。  注意:這注解只能寫在方法上

      ① 創建的對象在Spring容器中的標識(相當於xml配置的bean的id):默認是方法名,則在其他類中引用是引用該方法名
       也可使用name屬性:給當前@Bean註解方法 創建的對象 指定一個名稱(bean的id),則在其他類中引用的是我們指定的名稱。

      ② 如果有方法形參,注入數據的注入方式: 默認根據類型注入,如果根據類型注入方式失敗(有多個類型匹配),則根據名稱注入。

     */
    public QueryRunner createRunner(DruidDataSource dataSource){
        QueryRunner queryRunner = new QueryRunner(dataSource);
        return queryRunner;
    }

    //創建數據源對象
    @Bean
    public DruidDataSource createDruidDataSource(){
        DruidDataSource druidDataSource = new com.alibaba.druid.pool.DruidDataSource();
        druidDataSource.setUrl(url);
        druidDataSource.setUsername(username);
        druidDataSource.setPassword(password);
        druidDataSource.setDriverClassName(driverClassName);
        return druidDataSource;
    }

}
  • druid.properties(Druid數據庫連接池的配置文件)
url=jdbc:mysql://127.0.0.1:3306/spring
myusername=root
password=root
driverClassName=com.mysql.jdbc.Driver

當配置文件中的用戶名配置爲username時報錯: 百度:配置文件中 username 與 Mysql 關鍵字衝突(暫不明確)
在這裏插入圖片描述

報錯信息:

create connection SQLException, url: jdbc:mysql://127.0.0.1:3306/spring, errorCode 1045, state 28000
java.sql.SQLException: Access denied for user '周炜'@'localhost' (using password: YES)

通過純註解配置如何獲取容器

	//參數:配置類的字節碼  
  ApplicationContext applicationContext=  new AnnotationConfigApplicationContext(SpringConfig.class);

Spring整合Junit,Spring測試框架

  • 引入依賴
        <!--Spring測試包  封裝了junit-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
        
         <!--spring5及以上版本要求單元測試junit版本要高於或等於4.12-->
     	 <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
           <version>4.12</version>
        </dependency>

  • 測試類配置步驟
//1.使用@RunWith註解替換原有運行器
@RunWith(SpringJUnit4ClassRunner.class)
/*
2.使用@ContextConfiguration指定spring配置文件的位置
locations屬性:用於指定配置文件的位置。類路徑下,需要使用classpath:
	例:@ContextConfiguration(locations= {"classpath:beans.xml"})
classes屬性:當不使用xml配置時,用於指定spring配置類。
 */
@ContextConfiguration(classes = {SpringConfig.class})
public class SpringDBUtilsTest {
    //3.使用@Autowired給測試類中的變量注入數據
    @Autowired
    private  UserService userService;
    @Test
    public void SelectTest(){
        User user = userService.getById(3);
        System.out.println(user);
    }
}

注:Spring測試類擴展了JUnit,spring框架提供了一個運行器,可以讀取配置文件(或註解)來創建容器(即測試程序能自動創建spring容器,無須我們編碼創建)。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章