在 classpath 中扫描组件:
当在组件类上使用了特定的注解之后 , 还需要在 Spring 的配置文件中声明 <context:component-scan>:
- base-package 属性指定一个需要扫描的基类包 , Spring 容器将会扫描这个基类包里及其子包中的所有类。
- 当需要扫描多个包时 , 可以使用逗号分隔。
- 如果仅希望扫描特定的类而非基包下的所有类 , 可以使用 resource-pattern 属性过滤特定的类。
- <context:include-filter> 子节点表示要包含的目标类。
- <context:exclude-filter> 子节点表示要排除在外的目标类。
- <context:component-scan> 下可以拥有若干个 <context:include-filter> 和 <context:exclude-filter> 子节点。
<context:include-filter> 和 <context:exclude-filter> 子节点支持多种类型的过滤表达式:
类别 |
示例 |
说明 |
annotation |
com.xxx.XxxAnnotation |
所有标注 XxxAnnotation 的类。该类型采用目标类是否标注某个注解进行过滤 |
assinable |
com.xxx.XxxService |
所有继承或扩展 XxxService 的类。该类型采用目标类是否继承或扩展某个特定类进行过滤 |
aspectj |
com.xxx..*Service+ |
所有类名以 Service 结束的类及继承或者扩展他们的类。该类型采用 AspectJ 表达式进行过滤 |
regex |
com.xxx.anno..* |
所有 com.xxx.anno 包下的类。该类型采用正则表达式根据类的类名进行过滤 |
custom |
com.xxx.XxxTypeFilter |
采用 XxxTypeFilter 通过代码的方式定义过滤规则。该类必须实现 org.springframework.core.type.TypeFilter 接口 |
resource-pattern 属性过滤:
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 http://www.springframework.org/schema/beans/spring-beans.xsd 6 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> 7 8 <!-- 指定 Spring IOC 容器扫描的包--> 9 <!-- 10 resource-pattern="repository/*.class" 11 只扫描repository下的所有类 12 --> 13 <context:component-scan base-package="com.itdjx.spring.annotation" resource-pattern="repository/*.class"> 14 15 </context:component-scan> 16 17 </beans>
1 package com.itdjx.spring.annotation; 2 3 import com.itdjx.spring.annotation.controller.UserController; 4 import com.itdjx.spring.annotation.repository.UserRepository; 5 import com.itdjx.spring.annotation.service.UserService; 6 import org.springframework.context.ApplicationContext; 7 import org.springframework.context.support.ClassPathXmlApplicationContext; 8 9 /** 10 * @author Wáng Chéng Dá 11 * @create 2017-03-03 9:34 12 */ 13 public class Main { 14 15 public static void main(String[] args) { 16 ApplicationContext cxt = new ClassPathXmlApplicationContext("beans-annotation.xml"); 17 TestObject testObject = (TestObject) cxt.getBean("testObject"); 18 System.out.println(testObject); 19 20 UserController userController = (UserController) cxt.getBean("userController"); 21 System.out.println(userController); 22 23 UserService userService = (UserService) cxt.getBean("userService"); 24 System.out.println(userService); 25 26 UserRepository userRepository = (UserRepository) cxt.getBean("userRepository"); 27 System.out.println(userRepository); 28 29 } 30 }
控制台输出:
Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'testObject' available |
原因:配置文件中添加 resource-pattern="repository/*.class" 属性 , IOC 容器只扫描 repository 包下的类 , IOC 容器中只有 id 为 userRepository 的 bean 节点。
1 package com.itdjx.spring.annotation; 2 3 import com.itdjx.spring.annotation.controller.UserController; 4 import com.itdjx.spring.annotation.repository.UserRepository; 5 import com.itdjx.spring.annotation.service.UserService; 6 import org.springframework.context.ApplicationContext; 7 import org.springframework.context.support.ClassPathXmlApplicationContext; 8 9 /** 10 * @author Wáng Chéng Dá 11 * @create 2017-03-03 9:34 12 */ 13 public class Main { 14 15 public static void main(String[] args) { 16 ApplicationContext cxt = new ClassPathXmlApplicationContext("beans-annotation.xml"); 17 18 UserRepository userRepository = (UserRepository) cxt.getBean("userRepository"); 19 System.out.println(userRepository); 20 21 } 22 }
控制台输出:
com.itdjx.spring.annotation.repository.UserRepositoryImpl@1e153c5 |
<context:execlude-filter> 子节点:
- annotation 属性:
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 http://www.springframework.org/schema/beans/spring-beans.xsd 6 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> 7 8 <!-- 指定 Spring IOC 容器扫描的包 --> 9 <context:component-scan base-package="com.itdjx.spring.annotation"> 10 <!-- 排除包含(不包含) org.springframework.stereotype.Repository 的组件 --> 11 <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository"/> 12 </context:component-scan> 13 14 </beans>
1 package com.itdjx.spring.annotation; 2 3 import com.itdjx.spring.annotation.controller.UserController; 4 import com.itdjx.spring.annotation.repository.UserRepository; 5 import com.itdjx.spring.annotation.service.UserService; 6 import org.springframework.context.ApplicationContext; 7 import org.springframework.context.support.ClassPathXmlApplicationContext; 8 9 /** 10 * @author Wáng Chéng Dá 11 * @create 2017-03-03 9:34 12 */ 13 public class Main { 14 15 public static void main(String[] args) { 16 ApplicationContext cxt = new ClassPathXmlApplicationContext("beans-annotation.xml"); 17 TestObject testObject = (TestObject) cxt.getBean("testObject"); 18 System.out.println(testObject); 19 20 UserController userController = (UserController) cxt.getBean("userController"); 21 System.out.println(userController); 22 23 UserService userService = (UserService) cxt.getBean("userService"); 24 System.out.println(userService); 25 26 UserRepository userRepository = (UserRepository) cxt.getBean("userRepository"); 27 System.out.println(userRepository); 28 29 } 30 }
控制台输出:
Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'userRepository' available |
原因:IOC 容器中不包含 org.springframework.stereotype.Repository 的组件 , 也就是 IOC 容器中没有 id 为 userRepository 的 bean 节点。
- assignable 属性:
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 http://www.springframework.org/schema/beans/spring-beans.xsd 6 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> 7 8 <!-- 指定 Spring IOC 容器扫描的包 --> 9 <context:component-scan base-package="com.itdjx.spring.annotation"> 10 <!-- 排除(不包含) com.itdjx.spring.annotation.repository.UserRepository 以及他的实现类 --> 11 <context:exclude-filter type="assignable" expression="com.itdjx.spring.annotation.repository.UserRepository"/> 12 </context:component-scan> 13 14 </beans>
控制台输出:
com.itdjx.spring.annotation.TestObject@422e18 |
原因:IOC 容器中没有 id 为 userRepository 的 bean 节点。
<context:include-filter> 子节点:
- annotation 属性:
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 http://www.springframework.org/schema/beans/spring-beans.xsd 6 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> 7 8 <!-- 指定 Spring IOC 容器扫描的包 --> 9 <context:component-scan base-package="com.itdjx.spring.annotation"> 10 <!-- 包含 org.springframework.stereotype.Repository 的组件 --> 11 <context:include-filter type="annotation" expression="org.springframework.stereotype.Repository"/> 12 </context:component-scan> 13 14 </beans>
控制台输出:
com.itdjx.spring.annotation.TestObject@27ba32 |
<context:include-filter> 子节点没有生效:该子节点需要和 use-default-filters 属性配合使用。
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 http://www.springframework.org/schema/beans/spring-beans.xsd 6 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> 7 8 <!-- 指定 Spring IOC 容器扫描的包 --> 9 <context:component-scan base-package="com.itdjx.spring.annotation" use-default-filters="false"> 10 <!-- 包含 org.springframework.stereotype.Repository 的组件 --> 11 <context:include-filter type="annotation" expression="org.springframework.stereotype.Repository"/> 12 </context:component-scan> 13 14 </beans>
控制台输出:
Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'testObject' available |
原因:IOC 容器中只存在 id 为 userRepository 的 bean 节点 。
1 package com.itdjx.spring.annotation; 2 3 import com.itdjx.spring.annotation.controller.UserController; 4 import com.itdjx.spring.annotation.repository.UserRepository; 5 import com.itdjx.spring.annotation.service.UserService; 6 import org.springframework.context.ApplicationContext; 7 import org.springframework.context.support.ClassPathXmlApplicationContext; 8 9 /** 10 * @author Wáng Chéng Dá 11 * @create 2017-03-03 9:34 12 */ 13 public class Main { 14 15 public static void main(String[] args) { 16 ApplicationContext cxt = new ClassPathXmlApplicationContext("beans-annotation.xml"); 17 18 UserRepository userRepository = (UserRepository) cxt.getBean("userRepository"); 19 System.out.println(userRepository); 20 21 } 22 }
控制台输出:
com.itdjx.spring.annotation.repository.UserRepositoryImpl@1406a1 |
- assignable 属性:
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 http://www.springframework.org/schema/beans/spring-beans.xsd 6 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> 7 8 <!-- 指定 Spring IOC 容器扫描的包 --> 9 <context:component-scan base-package="com.itdjx.spring.annotation" use-default-filters="false"> 10 <!-- 包含 com.itdjx.spring.annotation.repository.UserRepository 以及他的实现类 --> 11 <context:include-filter type="assignable" expression="com.itdjx.spring.annotation.repository.UserRepository"/> 12 </context:component-scan> 13 14 </beans>
控制台输出:
com.itdjx.spring.annotation.repository.UserRepositoryImpl@af004b |