注解方式
- 摆脱繁琐的XML形式的bean与依赖注入配置
- 基于"声明式"的原则, 更适合轻量级的现代企业应用
- 让代码可读性变得更好, 研发人员拥有更好的开发体验
缺点
每次修改, 需要重新编译发布.
三类注解
- 组件类型注解 - 声明当前类的功能与职责
- 自动装配注解 - 根据属性特征自动注入对象
- 元数据注解 - 更细化的辅助IoC容器管理对象的注解
组件类型注解
注解 | 说明 |
---|---|
@Component | 组件注解, 通用注解, 被该注解描述的类将被IoC容器管理并实例化 |
@Controller | 语义注解, 说明当前类是MVC应用中的控制器类 |
@Service | 语义注解, 说明当前类是Service业务服务类 |
@Repository | 语义注解, 说明当前类用于业务持久层, 通常描述对应Dao类 |
组件注解示例
开启组件扫描, 才能使用注解
<!-- 在IoC容器初始化时自动扫描始终组件类型注解并完成实例化
@Repository
@Service
@Controller
@Component
-->
<context:component-scan base-package="com.imooc">
<!-- 可设置哪些包不被扫描 -->
<context:exclude-filter type="regex" expression="com.imooc.exl.*" />
</context:compoenent-scan>
组件类型注解示例
//组件类型注解默认beanId为类名首字母小写
@Repository()
public class UserDao{
}
或者可以设置一个beanId
@Repository("userDao")
public class UserDao{
}
自动装配注解
分配 | 注解 | 说明 |
---|---|---|
按类型装配 | @Autowired | 按容器内对象类型动态注入属性, 由Spring机构提供, 推荐使用 |
按类型装配 | @inject | 基于JSR-330(Dependency Injection for Java)标准, 其他同@Autowired, 但不支持required属性 |
按名称装配 | @Named | 与@inject配合使用, JSR-330规范, 按属性名自动装配属性 |
按名称装配 | @Resource | 基于JSR-250规范, 优先按名称、再按类型智能匹配, 推荐使用 |
按类型装配
public class UserService{
//Spring IoC容器会自动通过反射技术将属性private修饰符自动改为public, 直接进行赋值
//不再执行set方法
@Autowired
private UserDao udao;
//如果装配注解放在set方法上, 则自动按类型/名称对set方法参数进行注入
@Autowired
public void setUdao(UserDao udao){
this.udao=udao;
}
}
如果, 属性名在IoC容器里没有对应的beanId, 则会根据类型进行匹配, 建议使用属性名进行自动装配.
如果, 坚持使用按类型进行匹配, 可能会出现问题.
示例: 按类型匹配的风险
public class UserService{
@Autowired
private UserDao udao;
}
public interface IUserDao{
}
@Repository
public class UserDao implements IUserDao{
}
@Repository
public class UserOracleDao implements IUserDao{
}
如果, 类型是接口, 这个接口用多个实现类, 你不能保证注入的是哪个实现类
这里有两个解决办法:
- 方法1: 让一个类禁止IoC容器自动管理
- 方法2: 给一个类增加注解, @Primary
按名称进行装配
方法一: 不设置name
@Service
public class DepartmentService{
//如果不设置name属性, 则需要保证变量名和beanId一致, 方能进行自动装配
@Resource
private IUserDao userOracleDao;
}
方法二: 设置name
@Service
public class DepartmentService{
/**
1.@Resource设置name属性, 则按name在IoC容器中将bean注入
2.@Resource未设置name属性
2.1 以属性名作为bean name在IoC容器中匹配bean, 如有匹配则注入
2.2 如属性名未匹配, 则按类型进行匹配, 同@Autowired, 需加入@Primary解决类型冲突
使用建议: 在使用@Resource对象时推荐设置name或保证属性名与bean名称一致
*/
@Resource(name - "userOracleDao")
private IUserDao udao;
}
元数据注解
元数 | 说明 |
---|---|
@Primary | 按类型装配时出现多个相同类型对象 , 拥有此注解对象优先被注入 |
@PostConstruct | 描述方法, 相当于XML中init-method 配置的注解版本 |
@PreDestroy | 描述方法, 相当于XML中destroy-method 配置的注解版本 |
@Scope | 设置对象scope 属性 |
@Value | 为属性注入静态数据 |
示例1: @Scope
@Service
@Scope("prototype")//设置单例/多例
public class UserService {
}
示例2 @PostConstruct
@PostConstruct //和init-method属性 完全相同
public void init(){
}
示例3 @PreDestory
@PreDestroy //和destroy-method属性 完全相同
public void destroy(){
}
示例4 @value 设置静态属性
@Value("imooc.com")
private String metaData;
示例5 @Value 引导配置文件
@Value("${metaData}")
private String metaData;
@Value("${connection.password}")
private String password;
resource下新建config.properties
metaData=imooc.com
connection.driver=xxxxx
connection.url=xxx
connection.username=xxx
connection.password=xxx