通过注解配置Bean

时间:2022-07-16 19:06:09

【在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 }

运行结果;

通过注解配置Bean

 

(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>

运行结果:

通过注解配置Bean

 

(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>

运行结果:

通过注解配置Bean

 

(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>

运行结果:

通过注解配置Bean

注意:必须要将<context:component-scan>中的use-default-filters标签设置为false。否则将会执行默认的filter,结果是Respository、Controller、Service等等都会执行。

如:

通过注解配置Bean

 

 (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>

运行结果:

通过注解配置Bean

 

(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>

运行结果:

通过注解配置Bean

 

【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即可。