文章目錄
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容器,無須我們編碼創建)。