基于注解管理Bean
注解作为代码中的一种特殊标记,可以在编译、类加载和运行时被读取,执行相应处理。
注解实现自动装配的过程:
引入依赖
开启组件扫描
使用注解定义Bean
依赖注入
组件扫描
<!--开启组件扫描,指定包和子包中的内容将被扫描-->
<context:component-scan base-package="com.jobs.spring6"></context:component-scan>
<!--指定不被扫描的组件,包内其余组件全部扫描-->
<context:component-scan base-package="com.jobs.spring6">
<!--
context:exclude-filter指定排除规则
type:设定排除或包含的依据
type="annotation",根据注解排除,expression设置要排除的注解的全类名
type="assignable",根据类型排除,expression设置要排除的类型的全类名
-->
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
<context:exclude-filter type="assignable" expression="com.jobs.spring6.iocxml.User"/>
</context:component-scan>
<!--仅扫描包内指定组件-->
<context:component-scan base-package="com.jobs.spring6" use-default-filters="false">
<!--
context:include-filter指定在原有扫描规则上追加的规则
use-default-filters取值为false时标识关闭默认扫描规则,关闭后才能单独指定扫描目标
type="annotation",根据注解排除,expression设置要排除的注解的全类名
type="assignable",根据类型排除,expression设置要排除的类型的全类名
-->
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
<context:include-filter type="assignable" expression="com.jobs.spring6.iocxml.User"/>
</context:component-scan>
使用注解定义Bean
注解 | 说明 |
---|---|
@Component | 用于描述spring中的Bean,作为泛化的概念仅表示容器中的一个组件,可用于任何层次,四者功能相同 |
@Repository | 用于数据访问层(Dao)的类表示为spring中的Bean |
@Service | 用于业务层(Service)的类表示为spring中的Bean |
@Controller | 用于控制层(如springMVC的Controller)的类表示为spring中的Bean |
若是接口,则将注解加在实现类上
//@Repository
//@Service
//@Controller
//若不指定value,则默认用类名的小驼峰形式作为value
@Component(value = "user")//equal xml中<bean id="user" class="xxx"></bean>
public class User {
}
@Autowired注入
- 源码分析:
Target标识该注解能够作用的目标,可以在构造器、方法、参数、字段及派生注解中进行注入
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {
/**
* Declares whether the annotated dependency is required.
* 声明该注解标注的依赖是否需要一定存在于Spring容器中
* true为必须存在,如果不存在的话就抛出NoSuchBeanDefinitionException异常
* false不要求必须存在,如果不存在也不抛出异常(一般不建议设置,可能会引发线上事故)
* <p>Defaults to {@code true}.
*/
boolean required() default true;
}
- 使用方法:
在属性上方进行@Autowired
标识,交由spring进行对象的创建和引用;
但目标对象所在类必须由spring托管(已注册为Bean对象),否则无法进行自动注入; - 属性注入:
该注解会根据针对属性名定向寻找,例如注解Controller
中属性为UserService
的接口,会去UserServiceImpl
实现类中获取对象并注入注解处;
eg.
//注解写在接口实现类上
@Service
public class UserServiceImpl implements UserService{
//对属性进行注解,会自动寻找UserDao的实现类,将其对象注入
@Autowired
private UserDao userDao;
@Override
public void userService() {
System.out.println("userService");
userDao.userDao();
}
}
- Set注入:
在属性生成的set
方法上进行注解
eg.
private UserDao userDao;
@Autowired
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
- 构造方法注入
在属性生成构造方法上进行注解
eg.
private UserDao userDao;
@Autowired
public UserServiceImpl(UserDao userDao) {
this.userDao = userDao;
}
- 形参注入
同构造方法注入,但注解位置在形参前
eg.
private UserDao userDao;
public UserServiceImpl(@Autowired UserDao userDao) {
this.userDao = userDao;
}
- 只有一个有参构造(及不含无参构造、其它有参构造)时,可以省略
@Autowired
注解
eg.
//true
private UserDao userDao;
public UserServiceImpl(UserDao userDao) {
this.userDao = userDao;
}
//false
private UserDao userDao;
public UserServiceImpl(UserDao userDao) {
this.userDao = userDao;
}
public UserServiceImpl() {}
- 多个同类型Bean注入:
单一@Autowired
标签按照类型进行注入,加上@Qualifier
联合注解则可以按照名称进行注入(多个同类型Bean选择特定Bean)
eg.
@Autowired
@Qualifier(value = "userDaoImpl")
private UserDao userDao;
@Resource注入
@Resource | @Autowired |
---|---|
JDK扩展包内容,属于标准注解,当高于JDK11或低于JDK8时需要引入依赖以使用 | Spring框架内容 |
默认根据名称装配’byName’,未指定name时使用属性名作为name。name找不到则转为byType | 默认根据类型装配’byType’,可配合@Qualifier进行名称装配 |
作用在属性、setter方法 | 作用在属性、setter方法、构造方法、构造方法参数上 |
<!--@Resource-
<dependency>
<groupId>j
<artifactI
<version>2
</dependency>
- 根据名称进行注入
- 不指定名称,根据属性名称进行注入
- 根据类型注入
Spring全注解开发
代表不再使用Spring配置文件,使用配置类代替