扫描组件
Spring 能够从 classpath 下自动扫描,侦测和实例化具有特定注解的组件。
特定组件包括:
Component:
基本注解,标识了一个受 Spring管 理的组件
Respository:
标识持久层组件
Service:
标识服务层(业务层)组件
Controller:
标识表现层组件
对于扫描到组件,Spring 有默认的命名策略:使用非限定类名,第一个字母小写;
注解中通过 value 属性值标识组件的名称
使用注解后,还需要在 Spring 的配置文件中声明<context:component-scar>:
base-package
属性指定一个需要扫描的基类包,Spring 容器将会扫描这个基类包里及其子包中的所有的类;当需要扫描多个包时,可以使用逗号隔开
resource-pattern
扫描特定的类而非基包下的所有类
目录结构
![](https://img.haomeiwen.com/i2765653/6b6506dfa27e5813.png)
// 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();
}
}
网友评论