基于注解管理bean
注解和扫描
注解
和 XML 配置文件一样,注解本身并不能执行,注解本身仅仅只是做一个标记,具体的功能是框架检测到注解标记的位置,然后针对这个位置按照注解标记的功能来执行具体操作
本质上:所有一切的操作都是Java代码来完成的,XML和注解只是告诉框架中的Java代码如何执行
扫描
Spring 为了知道程序员在哪些地方标记了什么注解,就需要通过扫描的方式,来进行检测。然后根据注解进行后续操作
标识组件的常用注解
- @Component:将类标识为普通组件
- @Controller:将类标识为控制层组件
- @Service:将类标识为业务层组件
- @Repository:将类标识为持久层组件
@Controller、@Service、@Repository这三个注解只是在@Component注解的基础上起了三个新的名字。 对于Spring使用IOC容器管理这些组件来说没有区别。所以@Controller、@Service、@Repository这三个注解只是给开发人员看的,让我们能够便于分辨组件的作用
虽然它们本质上一样,但是为了代码的可读性,为了程序结构严谨得按规范标记
扫描组件(<context:component-scan>
)
type:设置排除或包含的依据
- annotation:根据注解排除或包含,expression中设置要排除或包含的注解的全类名
- assignable:根据类型排除或包含,expression中设置要排除或包含的类型的全类名
指定要排除的组件
context:exclude-filter标签:指定排除规则
spring-ioc-annotation.xml
<context:component-scan base-package="com.atguigu.threeLayer">
<!--排除-->
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
<context:exclude-filter type="assignable" expression="com.atguigu.threeLayer.controller.UserController"/>
</context:component-scan>
这里排除了@annotation
注解和UserController.java
仅扫描指定的组件
context:include-filter标签:指定在原有扫描规则的基础上追加的规则
因为默认规则即扫描指定包下所有类,使用排除需要将<context:component-scan>
中的use-default-filters
设置为false,表示关闭默认扫描规则
spring-ioc-annotation.xml
<context:component-scan base-package="com.atguigu.threeLayer" use-default-filters="false">
<!--包含-->
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
这里只扫描带@Controller
的注解的类
注解和扫描的使用
将扫描结果中加了注解的类作为组件进行管理——在IOC容器中添加对应的bean
创建spring-ioc-annotation.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!--扫描组件(可以在base-package中使用","添加多个扫描路径)-->
<context:component-scan base-package="com.atguigu.threeLayer">
</context:component-scan>
</beans>
添加注解:
- 在
UserController.java
中添加@Controller
注解 - 在
UserServiceImpl.java
中添加@Service
注解 - 在
UserDaoImpl.java
中添加@Repository
注解
SpringTest.java
@Test
public void IOCByAnnotation(){
ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-ioc-annotation.xml");
UserController userController = ioc.getBean(UserController.class);
System.out.println(userController);
//这里只要是【对象 instanceof 指定的类型】结果为true就可以获取到,所以可以自动获取到UserService有@Service注解的实现类UserServiceImpl的bean来实现多态
UserService userService = ioc.getBean(UserService.class);
System.out.println(userService);
UserDao userDao = ioc.getBean(UserDao.class);
System.out.println(userDao);
}
//运行结果:地址
bean的id
在使用XML方式管理bean的时候,每个bean都有一个唯一标识,便于在其他地方引用。现在使用注解后,每个组件仍然应该有一个唯一标识
默认情况
- 类名首字母小写就是bean的id。例如:UserController类对应的bean的id就是userController
自定义bean的id
- 可通过标识组件的注解的value属性设置自定义的bean的id。例如:@Controller(“UserController1”),将bean的id修改为"userService1"
默认情况:
UserController userController = ioc.getBean("userController",UserController.class);
自定义id:
@Controller("userController1")
UserController userController = ioc.getBean("userController1",UserController.class);