戴着假發的程序員出品
[查看視頻教程]
我們已經知道context:component-scan的配置可以通知spring掃描擁有spring標准注解的類。這些標注大致是:@Component、@Controller、@Service、@Repository。但是我們也可以通過context:include-filter配置通知spring掃描一些沒有標准注解但是我們希望spring幫我們管理的類。
context:include-filter有兩個必須的屬性:
type: 配置filter的類型,這個類型一共有以下五個值:
assignable-指定掃描某個接口派生出來的類
annotation-指定掃描使用某個注解的類
aspectj-指定掃描AspectJ表達式相匹配的類
custom-指定掃描自定義的實現了
org.springframework.core.type.filter.TypeFilter接口的類 regex-指定掃描符合正則表達式的類
expression: 根據type的不同,這個表達式的配置方式也不同。
我們直接看案例:
[1]assignable-指定掃描某個接口派生出來的類:
其中Info接口:
1 /** 2 * @author 戴着假發的程序員 3 * 4 * @description 5 */ 6 public interface Info { 7 }
Person類: 注意,我們在Person類上方添加了標准注解@Component,所以Person類會被spring加載
1 /** 2 * @author 戴着假發的程序員 3 * 4 * @description 5 */ 6 @Component 7 public class Person { 8 }
Student類:Student類沒有標注注解,理論上不會被Spring加載。但是Student類實現了接口Info
1 /** 2 * @author 戴着假發的程序員 3 * 4 * @description 5 */ 6 public class Student implements Info { 7 }
我們的spring配置:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xsi:schemaLocation="http://www.springframework.org/schema/beans 6 http://www.springframework.org/schema/beans/spring-beans.xsd 7 http://www.springframework.org/schema/context 8 http://www.springframework.org/schema/context/spring-context.xsd"> 9 10 <context:component-scan base-package="com.boxuewa.dk.demo5"> 11 <!-- 通知spring將實現接口Info的類也加載進來 --> 12 <context:include-filter type="assignable" expression="com.boxuewa.dk.demo5.Info"/> 13 </context:component-scan> 14 </beans>
測試:
1 @Test 2 public void testIncoudFilter(){ 3 ApplicationContext ac = 4 new ClassPathXmlApplicationContext("applicationContext-demo9.xml"); 5 System.out.println(ac.getBean(Person.class)); 6 System.out.println(ac.getBean(Student.class)); 7 }
結果:
我們發現spring已經幫我們加載了沒有注解的Student類。
[2]annotation-指定掃描使用某個注解的類:
我們自己創建一個注解:
1 /** 2 * @author 戴着假發的程序員 3 * 4 * @description 5 */ 6 @java.lang.annotation.Target({java.lang.annotation.ElementType.TYPE}) 7 @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) 8 public @interface DemoAno { 9 }
修改上面的Student類,Studnet類不再實現接口Info,但是在Student類上添加我們自己的注解。
1 /** 2 * @author 戴着假發的程序員 3 * 4 * @description 5 */ 6 @DemoAno 7 public class Student { 8 }
修改配置文件如下:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xsi:schemaLocation="http://www.springframework.org/schema/beans 6 http://www.springframework.org/schema/beans/spring-beans.xsd 7 http://www.springframework.org/schema/context 8 http://www.springframework.org/schema/context/spring-context.xsd"> 9 10 <context:component-scan base-package="com.boxuewa.dk.demo5"> 11 <!-- 通知spring將有指定注解的類加載進來 --> 12 <context:include-filter type="annotation" expression="com.boxuewa.dk.demo5.annotation.DemoAno"/> 13 </beans>
在測試:
我們發現Student類依然可以被加載。
[3]aspectj-指定掃描AspectJ表達式相匹配的類:比如要求加載某個類的派生類
這里需要添加AspectJ的依賴:
1 <dependency> 2 <groupId>org.springframework</groupId> 3 <artifactId>spring-aspects</artifactId> 4 <version>5.1.3.RELEASE</version> 5 </dependency>
我們添加一個新的User類:
1 /** 2 * @author 戴着假發的程序員 3 * 4 * @description 5 */ 6 public class User { 7 }
繼續修改我們的Stdeunt類,不實現接口,不需要注解,只要繼承User類即可。
1 /** 2 * @author 戴着假發的程序員 3 * 4 * @description 5 */ 6 public class Student extends User { 7 }
修改配置:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xsi:schemaLocation="http://www.springframework.org/schema/beans 6 http://www.springframework.org/schema/beans/spring-beans.xsd 7 http://www.springframework.org/schema/context 8 http://www.springframework.org/schema/context/spring-context.xsd"> 9 10 <context:component-scan base-package="com.boxuewa.dk.demo5"> 11 <!-- 通知spring所有繼承和擴展自指定類的類全部加載進來 --> 12 <context:include-filter type="aspectj" expression="com.boxuewa.dk.demo5.User+"/> 13 </context:component-scan> 14 </beans>
再測試:
我們會發現Stduent類依然會被spring加載。
[4]custom-指定掃描自定義的實現了org.springframework.core.type.filter.TypeFilter接口的類
我們繼續修改Student類,不實現接口,不添加注解,不繼承任何類。
1 /** 2 * @author 戴着假發的程序員 3 * 4 * @description 5 */ 6 public class Student{ 7 }
我們添加一個MyFilter實現TypeFilter接口:
1 /** 2 * @author 戴着假發的程序員 3 * 4 * @description 5 */ 6 public class MyFilter implements TypeFilter { 7 @Override 8 public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException { 9 //這里判斷讀取的類型是否是Student,如果是就返回true,否則返回false; 10 //返回true就會被spring加載,否則不加載 11 if(metadataReader.getClassMetadata().getClassName().equals(Student.class.getName())){ 12 return true; 13 } 14 return false; 15 }
修改配置:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xsi:schemaLocation="http://www.springframework.org/schema/beans 6 http://www.springframework.org/schema/beans/spring-beans.xsd 7 http://www.springframework.org/schema/context 8 http://www.springframework.org/schema/context/spring-context.xsd"> 9 10 <context:component-scan base-package="com.boxuewa.dk.demo5"> 11 <!-- 通知spring根據我們配置的MyFilter類進行加載 這里的 expression要配置我們自己的MyFilter --> 12 <context:include-filter type="custom" expression="com.boxuewa.dk.demo5.MyFilter"/> 13 </context:component-scan> 14 </beans>
測試:
我們的Student類依然可以被加載。
[5]regex-指定掃描符合正則表達式的類
這個是比較簡單的,就是通過我們給出的正則表達式進行匹配。
我們繼續修改配置:
<?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.boxuewa.dk.demo5"> <!-- 通過spring根據我們給出的正則表達式進行匹配 --> <context:include-filter type="regex" expression=".*.*dent"/> </context:component-scan> </beans>
在測試:
依然可以成功的加載Student類。