Spring – 通过注解配置Bean(8)
- 2020 年 3 月 17 日
- 筆記
扫描组件
Spring能够从classpath下自动扫描,侦测和实例化具有特定注解的组件。
特定组件包括: Component:
基本注解,标识了一个受Spring管理的组件 Respository:
标识持久层组件 Service:
标识服务层(业务层)组件 Controller:
标识表现层组件
对于扫描到组件,Spring有默认的命名策略:使用非限定类名,第一个字母小写;
注解中通过value属性值标识组件的名称
使用注解后,还需要在Spring的配置文件中声明<context:component-scar>:
base-package
属性指定一个需要扫描的基类包,Spring容器将会扫描这个基类包里及其子包中的所有的类;当需要扫描多个包时,可以使用逗号隔开 resource-pattern
扫描特定的类而非基包下的所有类
目录结构

// UserRepository public interface UserRepository { void save(); }
// UserRepositoryImpl @Repository("userRepository") public class UserRepositoryImpl implements UserRepository { @Override public void save() { System.out.println("UserRepository Save..."); } }
// UserController @Controller public class UserController { public void execute(){ System.out.println("UserController execute... "); } }
// UserService @Service public class UserService { public void add(){ System.out.println("UserService add......"); } }
// TestObject @Component public class TestObject { }
// Main public class Main { public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); TestObject to = (TestObject)ctx.getBean("testObject"); System.out.println(to); UserController tuserController = (UserController)ctx.getBean("userController"); System.out.println(tuserController); UserService userService = (UserService)ctx.getBean("userService"); System.out.println(userService); UserRepository userRepository = (UserRepository)ctx.getBean("userRepository"); System.out.println(userRepository); } }
// xml <!--指定Spring IOC容器扫描的包 --> <context:component-scan base-package="com.sangyu.test05.annotation"/> // resource-pattern 指定扫描的资源 <context:component-scan base-package="com.sangyu.test05.annotation" resource-pattern="repository/*.class"/>
<context:include-filter>:
子节点表示要包含的目标类 <context:exclude-filter>:
子节点表示要排除在外的目标类 <context:component-scar>:
下可以拥有若干个 <context:include-filter>
和<context:exclude-filter>
子节点
类别 |
示例 |
说明 |
---|---|---|
annotation |
com.test.XxxAnntation |
所有标注了XxxAnnotation的类。该类型采用目标类是否标注了某个注解进行过滤 |
assinable |
com.test.XxxService |
所有继承或扩展XxxService的类,该类型采用目标类是否继承或扩展某个特定类进行过滤 |
<!--type="annotation" 该类型采用目标类是否标注了某个注解进行过滤--> <!--context:exclude-filter 子节点指定排除哪些指定表达式的组件--> <context:component-scan base-package="com.sangyu.test05.annotation"> <context:exclude-filter expression="org.springframework.stereotype.Repository" type="annotation"/> </context:component-scan> <!--context:include-filter 子节点指定包含哪些表达式的组件,该子节点需要use-default-filters配合使用--> <context:component-scan base-package="com.sangyu.test05.annotation" use-default-filters="false"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Repository"/> </context:component-scan> <!--type="assignable" 所有继承或扩展XxxService的类,该类型采用目标类是否继承或扩展某个特定类进行过滤 --> <context:component-scan base-package="com.sangyu.test05.annotation"> <context:exclude-filter type="assignable" expression="com.sangyu.test05.annotation.repository.UserRepository"/> </context:component-scan> <context:component-scan base-package="com.sangyu.test05.annotation" use-default-filters="false"> <context:include-filter type="assignable" expression="com.sangyu.test05.annotation.repository.UserRepository"/> </context:component-scan>
使用@Autowired自动装配Bean
构造器,普通字段(即使是非public)一切具有参数的方法都可以应用@Autowired
注解
默认情况下,所有使用@Autowired
注解的属性都需要被设置,当Spring找不到匹配的Bean装配属性时,会抛出异常
// UserService @Service public class UserService { @Autowired private UserRepository userRepository; public void add() { System.out.println("UserService add......"); userRepository.save(); } } // 另一种方式 @Service public class UserService { private UserRepository userRepository; @Autowired public void setUserRepository(UserRepository userRepository){ this.userRepository = userRepository; } public void add() { System.out.println("UserService add......"); userRepository.save(); } }
// UserController @Controller public class UserController { @Autowired private UserService userService; public void execute() { System.out.println("UserController execute... "); userService.add(); } }
// Main public class Main { public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); UserController userController = (UserController) ctx.getBean("userController"); System.out.println(userController); userController.execute(); } }
若某一属性允许不被设置,可以设置@Autowired
注解的required属性为false
// Main public class Main { public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); UserRepository userRepository = (UserRepository)ctx.getBean("userRepository"); System.out.println(userRepository); } }
// TestObject //@Component 注释掉 public class TestObject { }
// 实现类 @Repository("userRepository") public class UserRepositoryImpl implements UserRepository { @Autowired(required = false) private TestObject testObject; @Override public void save() { System.out.println("UserRepository Save..."); System.out.println(testObject); } } // 接口 public interface UserRepository { void save(); }
两个类实现一个接口的情况
// 接口 public interface UserRepository { void save(); } // 实现类1 @Repository("userRepository") // 两个类实现一个接口 ,默认会按照设置的名字去查找实现类 public class UserRepositoryImpl implements UserRepository { @Autowired(required = false) private TestObject testObject; @Override public void save() { System.out.println("UserRepository Save..."); System.out.println(testObject); } } // 实现类2 @Repository public class UserJdbcRepository implements UserRepository { @Override public void save() { System.out.println("UserJdbcRepository save...."); } } // Main public class Main { public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); UserService userService = (UserService)ctx.getBean("userService"); System.out.println(userService); userService.add(); } }
// 另一种方式:使用@Qualifier @Service public class UserService { @Autowired @Qualifier("userJdbcRepository") private UserRepository userRepository; public void add() { System.out.println("UserService add......"); userRepository.save(); } }