四、Spring IoC
4、1什么是IoC
在傳統(tǒng)的 Java 應(yīng)用中,一個(gè)類想要調(diào)用另一個(gè)類中的屬性或方法,通常會(huì)先在其代碼中通過(guò) new 的方式將后者的對(duì)象創(chuàng)建出來(lái),然后才能實(shí)現(xiàn)屬性或方法的調(diào)用。但在 Spring 應(yīng)用中,Java 對(duì)象創(chuàng)建的控制權(quán)是掌握在 IoC 容器手里,開發(fā)者通過(guò)XML或注解的配置將Java對(duì)象的管理權(quán)交給IoC容器,對(duì)象的創(chuàng)建由Spring完成。當(dāng)開發(fā)者需要用到對(duì)象時(shí),可以直接從Spring中獲取對(duì)象,不需要再自行創(chuàng)建。
IoC 帶來(lái)的最大改變不是代碼層面的,而是從思想層面上發(fā)生了“主從換位”的改變。原本開發(fā)者是主動(dòng)的一方,它想要使用什么資源就會(huì)自己創(chuàng)建。但在 Spring 應(yīng)用中,IoC 容器掌握著主動(dòng)權(quán),開發(fā)者則變成了被動(dòng)的一方,等待 IoC 容器創(chuàng)建對(duì)象后使用。
在應(yīng)用開發(fā)中,并不是所有對(duì)象都交給Spring創(chuàng)建,開發(fā)者經(jīng)常將功能類的對(duì)象交給Spring去創(chuàng)建,這些類的對(duì)象創(chuàng)建后只需要調(diào)用功能,實(shí)現(xiàn)功能即可,但實(shí)體對(duì)象,因?yàn)槊看蝿?chuàng)建存儲(chǔ)的數(shù)據(jù)或代表的內(nèi)容都不盡相同,所以實(shí)體類的對(duì)象還是使用常規(guī)方式(new)來(lái)實(shí)現(xiàn)對(duì)象創(chuàng)建。
4、2Spring加載Bean
DAO層
public interface IDemoDAO {
public void show();
}
public class DemoDAO implements IDemoDAO {
@Override
public void show() {
System.out.println("我是DAO方法");
}
}
Service層
public interface IDemoService {
public void show();
}
public class DemoService implements IDemoService {
private IDemoDAO demoDAO=new DemoDAO();
@Override
public void show() {
demoDAO.show();
}
}
在applicationContext.xml中添加Bean配置
<!--bean標(biāo)簽聲明要?jiǎng)?chuàng)建的類,id為唯一標(biāo)識(shí),class為類的全路徑-->
<bean id="demoDAO" class="com.demo.DAO.Impl.DemoDAO"></bean>
<bean id="demoService" class="com.demo.service.Impl.DemoService"></bean>
獲取IoC創(chuàng)建的對(duì)象
//創(chuàng)建ApplicationContext,通過(guò)實(shí)例化ClassPathXmlApplicationContext獲取配置文件
ApplicationContext applicationContext= new ClassPathXmlApplicationContext("applicationContext.xml");
//getBeanDefinitionNames獲取配置文件中所有加載的Bean
String[] str=applicationContext.getBeanDefinitionNames();
for (String s : str) {
System.out.println(s);
}
//getBean通過(guò)Bean的id屬性獲取對(duì)象
IDemoService demoService1= (IDemoService) applicationContext.getBean("demoService");
demoService1.show();
4、3Spring注入對(duì)象
通過(guò)案例可以看到Spring通過(guò)配置,為我們創(chuàng)建了對(duì)象,但是目前我們遇到了問(wèn)題,問(wèn)題就是,我們?cè)趯?shí)現(xiàn)過(guò)程中,Service要引用DAO的對(duì)象進(jìn)行功能實(shí)現(xiàn),我們的DAO雖然交給了Spring去創(chuàng)建,但我們依舊需要手動(dòng)創(chuàng)建,也就是說(shuō)我們要想實(shí)現(xiàn)功能,在Service中就要依賴于DAO的對(duì)象實(shí)現(xiàn)功能,這樣的形式,我們也可以交給Spring幫我們解決,這就是SpringIoC中重要的功能—依賴注入(DI)
在applicationContext.xml中進(jìn)行修改
<bean id="demoDAO" class="com.demo.DAO.Impl.DemoDAO"></bean>
<bean id="demoService" class="com.demo.service.Impl.DemoService">
<!--property標(biāo)簽實(shí)現(xiàn)依賴注入,name屬性為調(diào)用類對(duì)象屬性的set方法,ref屬性為指向配置中的對(duì)象-->
<property name="demoDAO" ref="demoDAO"/>
</bean>
Service類修改
public class DemoService implements IDemoService {
private IDemoDAO demoDAO;
public void setDemoDAO(IDemoDAO demoDAO) {
this.demoDAO = demoDAO;
}
@Override
public void show() {
demoDAO.show();
}
}
4、4使用注解實(shí)現(xiàn)IoC
通過(guò)配置文件實(shí)現(xiàn)SpringIoC,可以很好的分離代碼和配置,有較高的解耦性,但操作較為繁雜,所以Spring又提供了以注解形式對(duì)IoC進(jìn)行配置的方式,雖然解耦性降低,但代碼實(shí)現(xiàn)較為輕便。
IoC核心注解:
- @Component 組件,通用的注解方式
- @Service 在業(yè)務(wù)邏輯層使用(service層)
- @Repository 在數(shù)據(jù)訪問(wèn)層使用(DAO層)
- @Controller 在控制層使用,控制器的聲明(Controller)
- @Autowired:用來(lái)實(shí)現(xiàn)依賴注入,Autowired會(huì)通過(guò)對(duì)象類型進(jìn)行注入,如在一個(gè)類中出現(xiàn)相同數(shù)據(jù)類型對(duì)象需要注入時(shí),需要配合@Qualifier(對(duì)象名)進(jìn)行組合注解進(jìn)行注入
- @Resource:用來(lái)實(shí)現(xiàn)依賴注入,Resource會(huì)先根據(jù)名稱查找要注入的對(duì)象,在根據(jù)對(duì)象類型查找注入對(duì)象,根據(jù)名稱查找時(shí),可以通過(guò)Resource的name屬性查找
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:component-scan標(biāo)簽對(duì)包進(jìn)行掃描,base-package屬性為要掃描的包,掃描時(shí)會(huì)講包下面的所有注解進(jìn)行掃描-->
<context:component-scan base-package="com.demo"/>
</beans>
DAO層
@Repository
public class DemoDAO implements IDemoDAO {
@Override
public void show() {
System.out.println("我是DAO方法");
}
}
Service層
@Service
public class DemoService implements IDemoService {
//@Autowired
//@Qualifier("demoDAO")
@Resource
private IDemoDAO demoDAO;
/*
public void setDemoDAO(IDemoDAO demoDAO) {
this.demoDAO = demoDAO;
}
*/
@Override
public void show() {
demoDAO.show();
}
}
獲取IoC對(duì)象文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-537773.html
//創(chuàng)建ApplicationContext,通過(guò)實(shí)例化ClassPathXmlApplicationContext獲取配置文件
ApplicationContext applicationContext= new ClassPathXmlApplicationContext("applicationContext.xml");
//getBeanDefinitionNames獲取配置文件中所有加載的Bean
String[] str=applicationContext.getBeanDefinitionNames();
for (String s : str) {
System.out.println(s);
}
//getBean通過(guò)Bean的id屬性獲取對(duì)象
IDemoService demoService1= (IDemoService) applicationContext.getBean("demoService");
demoService1.show();
4、5Resource注解和Autowired注解的區(qū)別
@Autowired 和 @Resource 都是用來(lái)實(shí)現(xiàn)依賴注入的注解(在 Spring/Spring Boot 項(xiàng)目中),但二者卻有著不同:文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-537773.html
- 來(lái)源不同:@Autowired 來(lái)自 Spring 框架,而 @Resource 來(lái)自于Java
- 依賴查找的順序不同:@Autowired 先根據(jù)類型再根據(jù)名稱查詢,而 @Resource 先根據(jù)名稱再根據(jù)類型查詢
- 支持的參數(shù)不同:@Autowired 只支持設(shè)置 1 個(gè)參數(shù),而 @Resource 支持設(shè)置 7 個(gè)參數(shù)
- 依賴注入的用法支持不同:@Autowired 既支持構(gòu)造方法注入,又支持屬性注入和 Setter 注入,而 @Resource 只支持屬性注入和 Setter 注入
到了這里,關(guān)于Spring第二講:SpringIoC控制反轉(zhuǎn)、依賴注入的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!