Spring 能够从 classpath 下自动扫描,侦测具有特定注解的组件,组件包括
-
@Component
:基本注解,标识了一个受 Spring 管理的组件 -
@Respository
:标识持久层组件 -
@Service
:标识服务层组件 -
@Controller
:标识表现层组件
命名政策:第一个字母小写,也可以在注解中通过 value
属性标识组件名称
//接口层
public interface UserRepository {
public void save();
}
//实现层
@Repository("userRepository")
public class UserRepositoryImpl implements UserRepository {
@Override
public void save() {
System.out.println("UserRepositoryImpl Save ...");
}
}
//业务层
@Service
public class UserService {
public void add() {
System.out.println("UserService add ... ");
}
}
//控制层
@Controller
public class UserController {
public void execute() {
System.out.println("UserController execute ... ");
}
}
Spring 默认情况下,注解的名字为类名的第一个字母小写,如 testObject
@Component
public class TestObject {}
注解的值也可以自己设定,后面使用 getBean()
调用的时候也可以使用自己设置的值。如以下默认注解名为 userRepositoryImpl
,可以使用 value
属性标识注解名,@Repository("userRepository")
@Repository()
public class UserRepositoryImpl implements UserRepository {
@Override
public void save() {
System.out.println("UserRepositoryImpl Save ...");
}
}
getBean()
方法中的参数,默认为注解后的第一个字母小写的类名,也可以使用自己用 value
标识的注解名
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans-annotation.xml");
TestObject o = (TestObject) ctx.getBean("testObject");
System.out.println(o);
UserController userController = (UserController) ctx.getBean("userController");
userController.execute();
UserRepository userRepository = (UserRepository) ctx.getBean("userRepository");
System.out.println(userRepository);
UserService userService = (UserService) ctx.getBean("userService");
System.out.println(userService);
}
- Bean 的基本配置如下,在 Spring 的配置文件中声明
<context:component-scan>
,然后在base-package
下声明需要扫描的基类包
<context:component-scan base-package="edu.just.spring.beans.annotation"></context:component-scan>
在 edu.just.spring.beans.annotation
包及子包下扫描,此时该包下所有注解过的类都能执行
- 使用
resource-pattern
属性来过滤
<context:component-scan base-package="edu.just.spring.beans.annotation"
resource-pattern="repository/*.class"></context:component-scan>
此配置标识只能执行 edu.just.spring.beans.annotation.repository
子包下的 Bean 的方法
- 使用
context:exclude-filter
属性来过滤,表示排除指定的类
annotation
:表示目标类是否标注了某个注解进行扫描
assignable
:表示目标类是否继承或扩展某个特定类
expression
: 注解的名称
<context:component-scan base-package="edu.just.spring.beans.annotation">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
</context:component-scan>
使用注解名进行排除,排除指定子包下注解为 Repository
的目标类
<context:component-scan base-package="edu.just.spring.beans.annotation">
<context:exclude-filter type="assignable" expression="edu.just.spring.beans.annotation.repository.UserRepository"/>
</context:component-scan>
使用接口名进行排除,排除指定子包下接口名为 UserRepository
的目标类
- 使用
context:include-filter
属性来过滤,表示要包含的类,同时需要设定use-default-filters
才可以使用
use-default-filters
:默认为true
,用来指示是否自动扫描带有@Component
、@Repository
、@Service
和@Controller
的类。
(PS:只有设置为false
时,才会扫描指定包含的类)
<context:component-scan base-package="edu.just.spring.beans.annotation" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
</context:component-scan>
使用注解名进行包含,此时只能执行标识为 Repository
的类
<context:component-scan base-package="edu.just.spring.beans.annotation" use-default-filters="false">
<context:include-filter type="assignable" expression="edu.just.spring.beans.annotation.repository.UserRepository"/>
</context:component-scan>
使用接口名字进行包含,此时只能包含接口名为 UserRepository
的目标类