<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
控制反轉(IOC)旨在提供一種更簡單的機制,來設定元件的依賴項,並在整個生命週期管理這些依賴項。通常,控制反轉可以分成兩種子型別:依賴注入(DI)和依賴查詢(DL),這些子型別各自又可以被進一步分解為 IOC 服務的具體實現
依賴拉取(Dependency Pull),即根據需要,從登入檔中提取依賴項,以下程式碼顯示了基於 Spring 的依賴拉取
public class DependencyPull { public static void main(String[] args) { ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("spring/app-context.xml"); ctx.getBean("renderer", MessageRenderer.class); } }
上下文依賴查詢(contextualized dependency lookup,CDL),同樣屬於依賴查詢的子型別,和依賴拉取有點類似,但在 CDL 中,查詢是針對管理資源的容器執行的,這個容器通常由應用程式伺服器或框架(Tomcat、JBoss、Spring)提供,比如以下程式碼顯示了一個提供依賴查詢服務的容器介面
public interface Container { // 根據key獲取相應的依賴項 Object getDependency(String key); }
CDL 通過讓元件實現以下程式碼介面來進行工作
public interface ManagedComponent { void performLookup(Container container); }
元件需要實現該介面,當容器準備好將依賴項傳遞給元件時,會依次呼叫每個元件的 performLookup()
方法,然後元件就可以使用 Container
介面查詢所需的依賴項
public class ContextualizedDependencyLookup implements ManagedComponent { private Dependency dependency; @Override public void performLookup(Container container) { this.dependency = (Dependency) container.getDependency("myDependency"); } @Override public String toString() { return dependency.toString(); } }
當在元件的建構函式中提供依賴項時,就會發生建構函式依賴注入
public class ConstructorInjection { private Dependency dependency; public ConstructorInjection(Dependency dependency) { this.dependency = dependency; } @Override public String toString() { return dependency.toString(); } }
Ioc 容器通過 JavaBean 樣式的 setter 方法注入元件的依賴項
public class SetterInjection { private Dependency dependency; public void setDependency(Dependency dependency) { this.dependency = dependency; } @Override public String toString() { return dependency.toString(); } }
在 Spring 中,還支援另一種被稱為欄位注入(field injection)的注入型別,在後面學習使用 @Autowire 註解進行自動裝配時將介紹該注入型別
Spring 的依賴注入容器的核心是 BeanFactory,它負責管理元件,包括依賴項以及它們的生命週期。如果我們想獲得一個元件(Bean),就必須建立一個實現了 BeanFactory 介面的範例,並對其進行設定
雖然 BeanFactory 可以通過程式設計方式設定,但更常見的做法是使用某種組態檔在外部對其進行設定。Bean 設定可以由實現 BeanDefinition 介面的類的範例來表示,對於任何實現了 BeanDefinitionReader 介面的 BeanFactory 實現類來說,都可以使用 PropertiesBeanDefinitionReader 或 XmlBeanDefinitionReader 從組態檔讀取 BeanDefinition 資料
定義一組介面:
public interface Oracle { String output(); } public class OracleImpl implements Oracle { @Override public String output() { return "hello world"; } }
接下來我們來看一看,Spring 的 BeanFactory 如何被初始化並用於獲取 Bean 範例
public class XmlConfigWithBeanFactory { public static void main(String[] args) { // DefaultListableBeanFactory是Spring提供的兩個主要BeanFactory實現之一 DefaultListableBeanFactory factory = new DefaultListableBeanFactory(); XmlBeanDefinitionReader rdr = new XmlBeanDefinitionReader(factory); // 使用XmlBeanDefinitionReader從XML檔案讀取BeanDefinition資訊 rdr.loadBeanDefinitions(new ClassPathResource("spring/xml-bean-factory-config.xml")); // 使用在XML組態檔中設定的名稱oracle來獲取bean Oracle oracle = (Oracle) factory.getBean("oracle"); System.out.println(oracle.getInfo()); } }
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="oracle" name="oracle" class="com.example.OracleImpl"/> </beans>
ApplicationContext 介面是 BeanFactory 的一個擴充套件,除了 DI 服務外,還提供其他如事務和 AOP 等服務。在開發基於 Spring 的應用程式時,建議通過 ApplicationContext 介面與 Spring 互動
對於 XML 設定,需要宣告應用程式需要的由 Spring 提供的名稱空間基礎資訊,下面所示設定僅宣告用於定義 bean 的名稱空間
<?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:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="provider" class="com.example.HelloWorldMessageProvider"/> <bean id="render" class="com.example.StandardOutMessageRender" p:messageProvider-ref="provider"/> </beans>
要想在應用程式使用 Spring 的註解支援,需要在 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 base-package="com.example" /> </beans>
<context:component-scan>
標記告訴 Spring 掃描程式碼,從而找到 @Component
等註解注入的 bean,以及支援在指定包(及其所有子包)下使用 @Autowire
等註解的 bean
設定類使用 @Configuration
註解,幷包含用 @Bean
註解的方法,這些方法由 IOC 容器直接呼叫來範例化 bean,bean 名稱與用於建立它的方法的名稱相同
@Configuration public class HelloWorldConfiguration { @Bean public MessageProvider provider() { return new HelloWorldMessageProvider(); } @Bean public MessageRender render() { StandardOutMessageRender render = new StandardOutMessageRender(); render.setMessageProvider(provider()); return render; } }
如果想從該類中讀取設定資訊,需要一個不同的 ApplicationContext 實現
public class HelloWorldSpringAnnotated { public static void main(String[] args) { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(HelloWorldConfiguration.class); MessageRender render = ctx.getBean("render", MessageRender.class); render.render(); } }
使用 XML 設定來設定 setter 注入,需要在 <bean>
標記下指定 <property>
標記,為其注入一個依賴項
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="provider" class="com.example.HelloWorldMessageProvider"/> <bean id="render" class="com.example.StandardOutMessageRender"> <property name="messageProvider" ref="provider"/> </bean> </beans>
如果使用註解,只需要向 setter 方法新增一個 @Autowired
註解
@Service("render") public class StandardOutMessageRender implements MessageRender { ... @Override @Autowired public void setMessageProvider(MessageProvider messageProvider) { this.messageProvider = messageProvider; } }
public class ConfigurableMessageProvider implements MessageProvider { private String message; public ConfigurableMessageProvider(String message) { this.message = message; } @Override public String getMessage() { return null; } }
使用 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:c="http://www.springframework.org/schema/c" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="oracle" name="oracle" class="com.example.OracleImpl"/> <!-- 使用 <constructor-arg> 標記 --> <bean id="messageProvider" class="com.example.ConfigurableMessageProvider"> <constructor-arg value="hello world" /> </bean> <!-- 使用c名稱空間 --> <bean id="provider" class="com.example.ConfigurableMessageProvider" c:message="hello world"/> </beans>
使用註解方式
@Service public class ConfigurableMessageProvider implements MessageProvider { private String message; @Autowired public ConfigurableMessageProvider( @Value("hello world") String message) { this.message = message; } @Override public String getMessage() { return null; } }
到此這篇關於Spring 控制反轉和依賴注入的具體使用的文章就介紹到這了,更多相關Spring 控制反轉和依賴注入內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45