Java开发常用的几个注解

Java 开发常用的注解有@Mapper @Repository(持久层)、@Service(业务层)、@Controller (控制层) 和 @Component(其它),以及 @Autowired 和 @Resource

@Mapper

从 mybatis3.4.0 开始加入了 @Mapper 注解,添加 @Mapper 注解的接口生成一个实现类, 目的就是为了不再写 mapper 映射文件, 把 mapper 这个 DAO 交給 Spring 管理。

@Repository

@Repository 对应数据访问层 Bean ,例如:

@Repository(value="userDao")
public class UserDaoImpl extends BaseDaoImpl<User> {
 ………
}

@Repository(value="userDao") 注解是告诉 Spring,让 Spring 创建一个名字叫“userDao”的 UserDaoImpl 实例。

当 Service 需要使用 Spring 创建的名字叫“userDao”的 UserDaoImpl 实例时,就可以使用 @Resource(name = "userDao") 注解告诉 Spring,Spring 把创建好的 userDao 注入给 Service 即可。

 // 注入 userDao,从数据库中根据用户 Id 取出指定用户时需要用到
 @Resource(name = "userDao")
 private BaseDao<User> userDao;

 

 

@Controller

@Controller 对应表现层的 Bean,也就是 Action,例如:

 @Controller
 @Scope("prototype")
 public class UserAction extends BaseAction<User>{
 ……
}

使用@Controller注解标识UserAction之后,就表示要把UserAction交给Spring容器管理,在Spring容器中会存在一个名字为"userAction"action,这个名字是根据UserAction类名来取的。注意:如果@Controller不指定其value【@Controller】,则默认的bean名字为这个类的类名首字母小写,如果指定value【@Controller(value="UserAction")】或者【@Controller("UserAction")】,则使用value作为bean的名字

这里的 UserAction 还使用了 @Scope 注解,@Scope("prototype") 表示将 Action 的范围声明为原型,可以利用容器的scope="prototype"来保证每一个请求有一个单独的Action来处理,避免strutsAction的线程安全问题。spring 默认scope 是单例模式(scope="singleton"),这样只会创建一个Action对象,每次访问都是同一Action对象,数据不安全,struts2 是要求每次次访问都对应不同的Actionscope="prototype" 可以保证当有请求的时候都创建一个Action对象

@Service

@Service 对应的是业务层 Bean,例如:

 @Service("userService")
 public class UserServiceImpl implements UserService {
 ………
}

@Service("userService") 注解是告诉 Spring,当 Spring 要创建 UserServiceImpl 的的实例时,bean 的名字必须叫做 "userService",这样当 Action 需要使用 UserServiceImpl 的的实例时, 就可以由 Spring 创建好的 "userService",然后注入给 Action:在 Action 只需要声明一个名字叫“userService”的变量来接收由 Spring 注入的 "userService" 即可,具体代码如下:

 // 注入 userService
 @Resource(name = "userService")
 private UserService userService;

但现在自己不能主动去 new“UserServiceImpl”类的实例,new“UserServiceImpl”类的实例的权力已经被 Spring 拿走了,只有 Spring 才能够 new“UserServiceImpl”类的实例,而 Action 只能等 Spring 创建好“UserServiceImpl”类的实例后,再“恳求”Spring 把创建好的“UserServiceImpl”类的实例给他,这样他才能够使用“UserServiceImpl”,这就是 Spring 核心思想“控制反转”,也叫“依赖注入”,“依赖注入”也很好理解,Action 需要使用 UserServiceImpl 干活,那么就是对 UserServiceImpl 产生了依赖,Spring 把 Acion 需要依赖的 UserServiceImpl 注入 (也就是“给”) 给 Action,这就是所谓的“依赖注入”。对 Action 而言,Action 依赖什么东西,就请求 Spring 注入给他,对 Spring 而言,Action 需要什么,Spring 就主动注入给他。

 

@Component

@Component 泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。    

 

 

@Resource 和 @Autowired

@Resource 和 @Autowired 都是做 bean 的注入时使用,其实 @Resource 并不是 Spring 的注解,它的包是 javax.annotation.Resource,需要导入,但是 Spring 支持该注解的注入。

1、共同点

两者都可以写在字段和 setter 方法上。两者如果都写在字段上,那么就不需要再写 setter 方法。

2、不同点

@Autowired 注解是按照类型(byType)装配依赖对象,默认情况下它要求依赖对象必须存在,如果允许 null 值,可以设置它的 required 属性为 false。如果我们想使用按照名称(byName)来装配,可以结合 @Qualifier 注解一起使用 (@Service 注解必须写名字)。如下:

public class TestServiceImpl {
    @Autowired
    @Qualifier("userDao")
    private UserDao userDao; 
}

@Resource

@Resource 默认按照 ByName 自动注入,由 J2EE 提供,需要导入包 javax.annotation.Resource。@Resource 有两个重要的属性:name 和 type,而 Spring 将 @Resource 注解的 name 属性解析为 bean 的名字,而 type 属性则解析为 bean 的类型。所以,如果使用 name 属性,则使用 byName 的自动注入策略,而使用 type 属性时则使用 byType 自动注入策略。如果既不制定 name 也不制定 type 属性,这时将通过反射机制使用 byName 自动注入策略。

 

public class TestServiceImpl {

    // 下面两种 @Resource 只要使用一种即可

    @Resource(name="userDao")

    private UserDao userDao; // 用于字段上

   

    @Resource(name="userDao")

    public void setUserDao(UserDao userDao) { // 用于属性的 setter 方法上

        this.userDao = userDao;

    }

}

 

注:最好是将 @Resource 放在 setter 方法上,因为这样更符合面向对象的思想,通过 set、get 去操作属性,而不是直接去操作属性。