Spring-IOC實現【02-其他實現方式】
Java配置方式
SpringBoot流行之後,Java 配置開始被廣泛使用。
Java配置本質上,就是使用一個Java類去代替xml配置,這種配置方式在SpringBoot中得到了廣泛的使用。
實現步驟如下:
1. 建立java專案
2. 引入相關jar包
3. 建立實體類
4. 建立配置檔案類
/** * 該類相當於 application.xml檔案 * @author dpb[波波烤鴨] * */ @Configuration public class AppJavaConfig { /** * 該方法生成一個Book物件,和application.xml檔案中的bean標籤一致 * 預設 id為方法名,可以通過name和value屬性自定義 * @return */ @Bean public Book getBook(){ return new Book(); } }
5. 測試呼叫
@org.junit.Test public void test1() { AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppJavaConfig.class); Book book = ac.getBean(Book.class); System.out.println(book); }
自動配置
前面這種配置方式,對於所有要使用的類都需要一個一個的配置。可以通過自動配置來簡化Bean的配置。
xml檔案配置
xml配置通過四個註解來實現,目前來說功能是一樣的
|註解|描述|
|:----|:-----|
|@Component|一般用在身份不明確的元件上|
|@Service|一般用在Service層|
|@Controller|一般用在控制層|
|@Repository|一般用在資料庫訪問層|
1. 需要在application.xml檔案中開啟註解掃描
<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" 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-4.3.xsd"> <!-- 開啟註解 配置掃描路徑 --> <context:component-scan base-package="com.dpb.javabean"/> <!-- 如果有多個路徑 ,號隔開 <context:component-scan base-package="com.dpb.javabean,com.dpb.factory"/> --> </beans>
2. java物件中新增對應的註解
3. 測試
簡單案例
1.建立專案
2.建立dao層
public interface IUserDao { public String add(); }
public class UserDaoImpl implements IUserDao { @Override public String add() { // TODO Auto-generated method stub return "hello ... "; } }
3.建立service層
public interface IUserService { public String add(); }
public class UserServiceImpl implements IUserService { private IUserDao dao; @Override public String add() { return dao.add(); } }
4.建立controller層
public class UserController { private IUserService service; public String add(){ return service.add(); } }
5.配置檔案中新增掃描
<!-- 開啟掃描com.sxt.*--> <context:component-scan base-package="com.sxt.controller,com.sxt.service.impl,com.sxt.dao.impl"/>
6.註解使用
dao
service
controller
7.測試
/** * 通過靜態工廠獲取Person物件 */ @Test public void test2() { // 獲取ApplicationContext物件 載入配置檔案 反射+xml解析 ApplicationContext ac = new ClassPathXmlApplicationContext("application.xml"); UserController bean = ac.getBean(UserController.class); System.out.println(bean.add()); }
掃描特殊配置
<context:component-scan base-package="com.itbaizhan" use-default-filters="false"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Service" /> </context:component-scan>
use-default-filters
表示使用使用spring預設提供的過濾器,
false表示不使用,true則表示使用。
一般來說,
true結合exclude-filter標籤使用,表示除去某個註解
false結合include標籤使用,表示包含某個註解
java程式碼配置
Java配置和XML配置基本一致,唯一不同的地方就是包掃描的方式。
四個註解是一樣的。
包掃描通過@ComponentScan來實現
1. Java配置類新增掃描註解
/** * 該類相當於 application.xml檔案 * @author dpb[波波烤鴨] * */ @Configuration // 該配置是必須的 @ComponentScan("com.dpb.javabean") public class AppJavaConfig { }
Java配置一樣可以實現精確的包掃描
/** * 該類相當於 application.xml檔案 * * @author dpb[波波烤鴨] * */ @Configuration // 該配置是必須的 @ComponentScan(value = "com.itbaizhan.bean", useDefaultFilters = false, includeFilters = { @ComponentScan.Filter(type = FilterType.ANNOTATION, value = Service.class) }) public class AppJavaConfig { }
2. JavaBean新增對應的註解
3. 測試
profile
在實際開發中,專案即將上線時,可能需要不停的在開發環境、生產環境、測試環境...之間進行切換。
Java配置實現
1. 建立實體類
2. 修改java配置類
/** * 該類相當於 application.xml檔案 * @author dpb[波波烤鴨] * */ @Configuration // 該配置是必須的 @ComponentScan("com.dpb.javabean") public class AppJavaConfig { /** * @Profile註解相當於一個標記,標記當前的dataSource是開發環境下的dataSource * @return */ @Bean("ds") @Profile("dev") // profile dev 設定 開發環境 public DataSource devDs(){ return new DataSource("http://dev1:8080/", "admin", "123456"); } @Bean("ds") @Profile("pro") // profile Pro 設定生產環境 public DataSource proDs(){ return new DataSource("http://pro1:8080/", "root", "666"); } }
3. 測試切換
@org.junit.Test public void test2() { AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(); // 設定使用哪種環境prodev ac.getEnvironment().setActiveProfiles("pro"); ac.register(AppJavaConfig.class); ac.refresh(); DataSource ds = ac.getBean(DataSource.class); System.out.println(ds); }
XML配置
通過xml配置實現profile,步驟如下:
1. 建立相關Bean
2. 在xml配置中配置bean
<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" 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-4.3.xsd"> <!-- 注意,beans標籤要寫在其他標籤的後面。 --> <beans profile="dev"> <bean class="com.dpb.javabean.DataSource"> <property name="url" value="dev-url"/> <property name="userName" value="aaa"/> <property name="password" value="111"/> </bean> </beans> <beans profile="pro"> <bean class="com.dpb.javabean.DataSource"> <property name="url" value="pro-url"/> <property name="userName" value="999"/> <property name="password" value="222"/> </bean> </beans> </beans>
3.測試資料
/** * * @author dpb[波波烤鴨] * */ public class Test { @org.junit.Test public void test1() { ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext(); ac.getEnvironment().setActiveProfiles("dev"); ac.setConfigLocation("application.xml"); ac.refresh(); DataSource bean = ac.getBean(DataSource.class); System.out.println(bean); } }
條件註解
Profile實際上就是條件註解的一種特殊形式,即條件註解更加靈活,使用者可以根據各種不同的條件使用不同的Bean。
條件註解在SpringBoot中使用非常廣泛。SpringBoot中提供了許多自動化的配置,例如資料庫配置,SpringBoot使用條件註解提前配置好許多常用的類,使用條件註解,在某一個條件滿足時,這些配置就會生效。
1.建立介面
/** * 條件註解 *1.定義介面 * @author dpb[波波烤鴨] * */ public interface ShowCmd { String show(); }
2.建立介面的實現類
/** * 註冊介面的實現類 * @author dpb[波波烤鴨] * */ public class LinuxShowCmd implements ShowCmd{ @Override public String show() { // TODO Auto-generated method stub return "Liunx ls"; } }
/** * 註冊介面的實現類 * @author dpb[波波烤鴨] * */ public class WinShowCmd implements ShowCmd{ @Override public String show() { // TODO Auto-generated method stub return "Windows dir"; } }
3.定義條件Condition
/** * 自定義的條件 * @author dpb[波波烤鴨] * */ public class LinuxConditionShow implements Condition{ /** * 條件匹配的方法 * true 條件匹配 * false 條件不匹配 */ @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { // 獲取profile引數 String osName[] = context.getEnvironment().getActiveProfiles(); for (String name : osName) { System.out.println(name); if(name.contains("linux")){ return true; } } return false; } }
/** * 自定義的條件 * @author dpb[波波烤鴨] * */ public class WindowsConditionShow implements Condition{ /** * 條件匹配的方法 * true 條件匹配 * false 條件不匹配 */ @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { String osName[] = context.getEnvironment().getActiveProfiles(); for (String name : osName) { System.out.println(name); if(name.contains("window")){ return true; } } return false; } }
4.java配置檔案
@Configuration public class JavaConfig { @Bean("cmd") // 關聯條件設定 @Conditional(LinuxShowCondition.class) public LinuxShowCmd showLinux(){ return new LinuxShowCmd(); } @Bean("cmd") // 關聯條件設定 @Conditional(WindowsShowCondition.class) public WindowsShowCmd showWindows(){ return new WindowsShowCmd(); } }
5.測試呼叫
@org.junit.Test public void test2() { AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(); // 設定使用哪種環境 Linux和Window; ac.getEnvironment().setActiveProfiles("linux"); ac.register(AppJavaConfig.class); ac.refresh(); ShowCmd show = (ShowCmd) ac.getBean("cmd"); System.out.println(show.show()); }
Bean的作用域
作用域 | 說明 |
---|---|
prototype | 每次請求,都是一個新的Bean【享元模式】 |
singleton | bean是單例的 |
request | 在一次請求中,bean的宣告週期和request同步 |
session | bean的生命週期和session同步 |
在spring的配置中,預設情況下,bean都是單例的(singleton)。無論獲取多少次,獲取到的都是同一個bean
java配置檔案中
application.xml配置檔案中
混合配置
開發中可能既有配置檔案存在,也在使用java配置的方式,這時候可以使用@ImportResource來實現
1.新增application.xml檔案
<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" 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-4.3.xsd"> <bean class="com.dpb.javabean.UserBean" ></bean> </beans>
2.java配置檔案
/** * 該類相當於 application.xml檔案 * @author dpb[波波烤鴨] * */ @Configuration @ImportResource("classpath:application.xml") public class AppJavaConfig { @Bean Book book(){ return new Book(); } }