【在classpath中扫描组件】
1.组件扫描(component scanning):Spring 能够从classpath下自动扫描,侦测和实例化具有特定注解的组件。
2.特定组件包括:
--@Component:基本注解,标识了一个受Spring管理的组件。
--@Respository:标识持久层组件
--@Service:标识服务层(业务层)组件
--@controller:标识表现层组件
3.对于扫描到的组件,Spring有默认的命名策略:使用非限定类名,第一个字母小写,也可以在注解中通过value属性值标识组件的名称。
4.当在组件类上使用了特定的注解之后,还需要再Spring的配置文件中声明<context:component-scan>:
--base-package属性指定一个需要扫描的基类包,Spring容器将会扫描这个基类包里及其子包中的所有类。
--当需要扫描多个包时,可以用逗号隔开。
--如果仅希望扫描特定的类而非基类包下的所有类,可使用resource-pattern属性过滤特定的类:
示例:<context:component-scan
base-package="com.hk.beans"
resource-pattern="auowire/*.class"/>
--<context:include-filter>:子节点表示要包含的目标类
--<context:exclude-filter>:子节点表示要排除在外的目标类
--<context:component-scan>下可以拥有若干个<context:include-filter>和<context:exclude-filter>子节点
(1)
/spring-1/src/com/hk/beans/annotation/Main.java:
1 package com.hk.beans.annotation; 2 3 import org.springframework.context.ApplicationContext; 4 import org.springframework.context.support.ClassPathXmlApplicationContext; 5 import com.hk.beans.annotation.controller.UserController; 6 import com.hk.beans.annotation.repository.UserRespository; 7 import com.hk.beans.annotation.service.UserService; 8 9 public class Main { 10 public static void main(String[] args) { 11 ApplicationContext ctx = new ClassPathXmlApplicationContext("beans-annotation.xml"); 12 TestObject to = (TestObject) ctx.getBean("testObject"); 13 System.out.println(to); 14 15 UserController userController = (UserController) ctx.getBean("userController"); 16 System.out.println(userController); 17 18 UserService userService = (UserService) ctx.getBean("userService"); 19 System.out.println(userService); 20 21 UserRespository userRespository = (UserRespository) ctx.getBean("userRepository"); 22 System.out.println(userRespository); 23 } 24 }
/spring-1/src/com/hk/beans/annotation/TestObject.java:
1 package com.hk.beans.annotation; 2 3 import org.springframework.stereotype.Component; 4 5 @Component 6 public class TestObject { 7 8 }
/spring-1/src/com/hk/beans/annotation/controller/UserController.java:
1 package com.hk.beans.annotation.controller; 2 3 import org.springframework.stereotype.Controller; 4 5 @Controller 6 public class UserController { 7 public void execute(){ 8 System.out.println("UserController execute..."); 9 } 10 }
/spring-1/src/com/hk/beans/annotation/repository/UserRespository.java:
1 package com.hk.beans.annotation.repository; 2 3 public interface UserRespository { 4 void save(); 5 }
/spring-1/src/com/hk/beans/annotation/repository/UserRespositoryImpl.java:
1 package com.hk.beans.annotation.repository; 2 3 import org.springframework.stereotype.Repository; 4 5 @Repository("userRepository") 6 public class UserRespositoryImpl implements UserRespository { 7 @Override 8 public void save() { 9 System.out.println("'UserRepository Save..."); 10 } 11 }
/spring-1/src/com/hk/beans/annotation/service/UserService.java:
1 package com.hk.beans.annotation.service; 2 3 import org.springframework.stereotype.Service; 4 5 @Service 6 public class UserService { 7 public void add(){ 8 System.out.println("UserService add.."); 9 } 10 }
运行结果;
(2)可以通过resource-pattern指定扫描的资源
beans-annotation.xml;
1 <!-- 指定Spring IOC 容器扫描的包 --> 2 <context:component-scan base-package="com.hk.beans.annotation" 3 resource-pattern="repository/*.class"> 4 </context:component-scan>
运行结果:
(3)<context:exclude-filter>标签测试
context:exclude-filter 子节点指定排除哪些表达式的组件 。
beans-annotation.xml;
1 <!-- 指定Spring IOC 容器扫描的包 --> 2 <context:component-scan base-package="com.hk.beans.annotation"> 3 <context:exclude-filter type="annotation" 4 expression="org.springframework.stereotype.Repository"/> 5 </context:component-scan>
运行结果:
(4)context:include-filter标签测试
context:include-filter子节点指定包含哪些表达式的组件,该子节点需要use-default-filter配合使用。
beans-annotation.xml:
1 <context:component-scan base-package="com.hk.beans.annotation" use-default-filters="false"> 2 3 <context:include-filter type="annotation" 4 expression="org.springframework.stereotype.Repository"/> 5 </context:component-scan>
运行结果:
注意:必须要将<context:component-scan>中的use-default-filters标签设置为false。否则将会执行默认的filter,结果是Respository、Controller、Service等等都会执行。
如:
(5)
beans-annotation.xml:
1 <context:component-scan base-package="com.hk.beans.annotation"> 2 <context:exclude-filter type="assignable" 3 expression="com.hk.beans.annotation.repository.UserRespository"/> 4 </context:component-scan>
运行结果:
(6)
beans-annotation.xml:
1 <context:component-scan base-package="com.hk.beans.annotation" 2 use-default-filters="false"> 3 <context:include-filter type="assignable" 4 expression="com.hk.beans.annotation.repository.UserRespository"/> 5 </context:component-scan>
运行结果:
【Bug无处不在】
1.中途遇到的bug:异常信息如下:
1 Exception in thread "main" org.springframework.beans.factory.BeanDefinitionStoreException: Unexpected exception parsing XML document from class path resource [beans-annotation.xml]; nested exception is java.lang.NoClassDefFoundError: org/springframework/aop/TargetSource 2 at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:414) 3 at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:336) 4 at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:304) 5 at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:181) 6 at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:217) 7 at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:188) 8 at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:252) 9 at org.springframework.context.support.AbstractXmlApplicationContext.loadBeanDefinitions(AbstractXmlApplicationContext.java:127) 10 at org.springframework.context.support.AbstractXmlApplicationContext.loadBeanDefinitions(AbstractXmlApplicationContext.java:93) 11 at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:129) 12 at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:612) 13 at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:513) 14 at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139) 15 at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83) 16 at com.hk.beans.annotation.Main.main(Main.java:12) 17 Caused by: java.lang.NoClassDefFoundError: org/springframework/aop/TargetSource 18 at org.springframework.context.annotation.AnnotationConfigUtils.registerAnnotationConfigProcessors(AnnotationConfigUtils.java:154) 19 at org.springframework.context.annotation.ComponentScanBeanDefinitionParser.registerComponents(ComponentScanBeanDefinitionParser.java:150) 20 at org.springframework.context.annotation.ComponentScanBeanDefinitionParser.parse(ComponentScanBeanDefinitionParser.java:88) 21 at org.springframework.beans.factory.xml.NamespaceHandlerSupport.parse(NamespaceHandlerSupport.java:74) 22 at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseCustomElement(BeanDefinitionParserDelegate.java:1411) 23 at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseCustomElement(BeanDefinitionParserDelegate.java:1401) 24 at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.parseBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:172) 25 at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.doRegisterBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:142) 26 at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.registerBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:94) 27 at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.registerBeanDefinitions(XmlBeanDefinitionReader.java:508) 28 at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:392) 29 ... 14 more 30 Caused by: java.lang.ClassNotFoundException: org.springframework.aop.TargetSource 31 at java.net.URLClassLoader$1.run(URLClassLoader.java:366) 32 at java.net.URLClassLoader$1.run(URLClassLoader.java:355) 33 at java.security.AccessController.doPrivileged(Native Method) 34 at java.net.URLClassLoader.findClass(URLClassLoader.java:354) 35 at java.lang.ClassLoader.loadClass(ClassLoader.java:425) 36 at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308) 37 at java.lang.ClassLoader.loadClass(ClassLoader.java:358) 38 ... 25 more
解决方法:
导入一个jar包:spring-aop-4.3.3.RELEASE.jar即可。