spring(一)註解使用(@Configuration 、@Bean、@ComponentScan、@TypeFilter)
1、spring的框架:
spring的核心是控制反轉(IOC)和橫向切面(AOP)
- 核心容器:核心容器提供 Spring 框架的基本功能。核心容器的主要元件是
BeanFactory
,它是工廠模式的實現。BeanFactory
使用控制反轉 (IOC) 模式將應用程式的配置和依賴性規範與實際的應用程式程式碼分開。 - Spring 上下文:Spring 上下文是一個配置檔案,向 Spring 框架提供上下文資訊。Spring 上下文包括企業服務,例如 JNDI、EJB、電子郵件、國際化、校驗和排程功能。
- Spring AOP
- Spring DAO:JDBC DAO 抽象層提供了有意義的異常層次結構,可用該結構來管理異常處理和不同資料庫供應商丟擲的錯誤訊息。異常層次結構簡化了錯誤處理,並且極大地降低了需要編寫的異常程式碼數量(例如開啟和關閉連線)。Spring DAO 的面向 JDBC 的異常遵從通用的 DAO 異常層次結構。
- Spring ORM:Spring 框架插入了若干個 ORM 框架,從而提供了 ORM 的物件關係工具,其中包括 JDO、Hibernate 和 iBatis SQL Map。所有這些都遵從 Spring 的通用事務和 DAO 異常層次結構。
- Spring Web 模組:Web 上下文模組建立在應用程式上下文模組之上,為基於 Web 的應用程式提供了上下文。所以,Spring 框架支援與 Jakarta Struts 的整合。Web 模組還簡化了處理多部分請求以及將請求引數繫結到域物件的工作。
- Spring MVC 框架:MVC 框架是一個全功能的構建 Web 應用程式的 MVC 實現。通過策略介面,MVC 框架變成為高度可配置的,MVC 容納了大量檢視技術,其中包括 JSP、Velocity、Tiles、iText 和 POI。
Spring 框架的功能可以用在任何 J2EE 伺服器中,大多數功能也適用於不受管理的環境。Spring 的核心要點是:支援不繫結到特定 J2EE 服務的可重用業務和資料訪問物件。毫無疑問,這樣的物件可以在不同 J2EE 環境 (Web 或 EJB)、獨立應用程式、測試環境之間重用。
2、spring註解開發
spring從3.0開始支援註解開發,通過註解方式代替xml定義bean檔案,例:
(1)xml定義bean檔案:
<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-3.0.xsd">
<bean id="helloBean" class="com.test.HelloWorldImpl">
</beans>
註解方式為:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.test.HelloWorld;
import com.test.HelloWorldImpl;
@Configuration
public class AppConfig {
@Bean(name="helloBean")
public HelloWorld helloWorld() {
return new HelloWorldImpl();
}
}
@configuration為配置類註解
(2)@Configuration 和@Bean ( xml定義、呼叫(以前),註解開發(現在))
以前:
xml定義:
<bean id="person" class="com.test.Person">
<property name="age" value="18" > </property>
<property name="name" value="haozi" > </property>
</bean>
main方法中呼叫:
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathApplicationContext("beans.xml");
Person bean = applicationContext.getBean(Person.class); //或者getBean("person"); id獲取
Sysytem.out.println(bean);
}
現在:
@Configuration //告訴spring是一個配置類
public class AppConfig {
@Bean(name="person") //給容器註冊一個bean
public Person person() {
return new Person("haozi", 20);
}
}
(3)@ComponentScan自動掃描元件和掃描規則
首先建立三個元件類:
@Controller類
@Controller
public class bookController {
}
@Service類
@Service
public class bookService {
}
@Repository類
@Respository
public class bookDao {
}
包掃描(配置在了配置類中)
@Configuation
@ComponentScan(value = "com.test")
public class mainConfig {
@Bean(name="person") //給容器註冊一個bean
public Person person() {
return new Person("haozi", 20);
}
}
測試類test:
public class test {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathApplicationContext(mainConfig.class);
String[] defintionNames = applicationContext.getBeanDefinitionNames();
for(String name: defintionNames ) {
System.out.println(name);
}
}
}
此時會列印:
mainConfig
bookController
bookService
bookDao
可以選擇只掃描哪些,只需要在@Component部分:(excludeFilter排除,includeFilter只包括)
@Component(value="com.test",excludeFilters={@Filter(type=FilterType.ANNOTATION,
classes=Contoller.class)})
此時僅排除Controller,由於classes可以是陣列,因此可以排除多個即classes={Controller, Service}
同時可以選擇是否禁用過濾:
useDefaultFilter=false/true
下面是不禁用:
@Component(value="com.test",excludeFilters={@Filter(type=FilterType.ANNOTATION,
classes={Contoller.class})}, useDefaultFilter=false)
最後,掃描@ComponenScan可以寫在@ComponentScans()中。
(4)TypeFilter指定過濾方式:
FilterType.ASSIGNABLE_TYPE 按照指定型別
FlterType.ASPECTJ 按照ASPECTJ表示式
FilterType.REGEX 正則表示式
FilterType.CUSTOM 自定義方式過濾
@Component(value="com.test",includeFilters={
@Filter(type=FilterType.ANNOTATION,classes={Contoller.class})
@Filter(type=FilterType.ASSIGNABLE_TYPE, classes={bookService.class})
}, useDefaultFilter=false)
只要是bookService這種型別都會顯示。
重點講解自定義(Custom)
首先建一個類myTypeFilter類:
public class myTypeFilter implements TypeFilter {
// MetadataReader 讀取當前類資訊
// MetadataReaderFactory 可以獲取其他類資訊
@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory ) throws IOException {
ClassMetaName classMetaData = metadataReader.getClassMetaData(); //獲取當前類資訊
String className = classMetaData.getClassName();
System.out.println("——" + className);
if(className.contains("er")) { //如果類名包含er,則返回true,可以顯示
return true;
}
return false;
}
}
下面指定自定義獲取:
@Component(value="com.test",includeFilters={
@Filter(type=FilterType.ANNOTATION,classes={Contoller.class})
@Filter(type=FilterType.CUSTOM, classes={myTypeFilter.class})
}, useDefaultFilter=false)
那麼顯示型別就會用:
bookService