您好,欢迎访问代理记账网站
  • 价格透明
  • 信息保密
  • 进度掌控
  • 售后无忧

Spring注解(@Autowired@Qualifier@Resource@Controller@Service等)

Spring注解

2021/5/7 周五
学习内容:@Autowired,@Qualifier,@Resource,@AliasFor,@Component,@Controller,@Scope,@Service,@Repository等。

如有错误,欢迎在评论区指出,非常感谢!


一、为什么要用注解

传统的Spring做法是使用.xml文件来对bean进行注入或者是配置aop、事物,这么做有两个缺点:

  1. 如果所有的内容都配置在.xml文件中,那么.xml文件将会十分庞大;如果按需求分开.xml文件,那么.xml文件又会非常多。总之这将导致配置文件的可读性与可维护性变得很低。
  2. 在开发中在.java文件和.xml文件之间不断切换,是一件麻烦的事,同时这种思维上的不连贯也会降低开发的效率。

为了解决这两个问题,Spring引入了注解,通过"@XXX"的方式,让注解与Java Bean紧密结合,既大大减少了配置文件的体积,又增加了Java Bean的可读性与内聚性

二、Spring注解的使用

使用前必须告诉spring一下我要使用注解了,告诉的方式有很多,<context:component-scan base-package=“xxx” /> 是一种最简单的,spring会自动扫描xxx路径下的注解

Spring中的注解大概可以分为两大类:

  1. spring的bean容器相关的注解,或者说bean工厂相关的注解:
    @Autowired,@Required,@PostConstruct, @Qualifier, @AliasFor等;

  2. springmvc相关的注解:
    @Controller,@Service,@RequestMapping,@ResponseBody等。

三、常用的Bean容器相关注解

1. @Autowired

@Autowired顾名思义,就是自动装配,其作用是为了消除代码Java代码里面的getter/setter与bean属性中的property

@Autowired默认按类型匹配的方式,当Spring发现@Autowired注解时,将自动在代码上下文中找到和其匹配的Bean,当有且仅有一个匹配的Bean时,Spring将其注入@Autowired标注的变量中

@Autowired 是我们使用得最多的注解,其实就是 autowire=byType ,就是根据类型的自动注入依赖(基于注解的依赖注入),可以被使用在属性域,方法,构造函数上。

2. @Qualifier(指定注入Bean的名称)

@Qualifier 就是 autowire=byName, @Qualifier 通常和@Autowired一起使用,一般在两个或者多个bean是相同的类型时,spring注入会出现混乱,就需要使用 @Qualifier(“xxBean”) 来指定Bean的名称

  • 例如
    定义一个Car接口,两个实现类BMWCar和BenzCar:
    再写一个CarFactory,引用car(这里先不用@Qualifier注解):
    Car接口有两个实现类,Spring并不知道应当引用哪个实现类。

通常有两种解决办法:
(1) 在配置文件中删除其中一个实现类,Spring会自动去base-package下寻找Car接口的实现类,发现Car接口只有一个实现类,便会直接引用这个实现类。
(2) 实现类就是有多个该怎么办?此时可以使用@Qualifier注解来指定Bean的名称:

@Autowired
@Qualifier("bmwCar")
private ICar car;

此处会注入名为"bmwCar"的Bean。

3. @Resource
@Resource(name="tiger")
private Tiger tiger;

@Resource(type=Monkey.class)
private Monkey monkey;

@Resource的装配顺序
(1) @Resource后面没有任何内容,默认通过name属性去匹配bean,找不到再按type去匹配
(2) 指定了name或者type则根据指定的类型去匹配bean
(3) 指定了name和type则根据指定的name和type去匹配bean,任何一个不匹配都将报错

@Resource@Autowired 的区别:

(1) @Autowired默认按照byType方式进行bean匹配,@Resource默认按照byName方式进行bean匹配

(2) @Autowired是Spring的注解,@Resource是J2EE的注解,这个看一下导入注解的时候这两个注解的包名就一清二楚了
Spring属于第三方的,J2EE是Java自己的东西,因此,建议使用@Resource注解,以减少代码和Spring之间的耦合。

4. @AliasFor

(1)组合注解
@AliasFor可以把多个元注解的属性组合在一起形成新的注解,从而到达到便捷的目的。这样的注解我们可以称之为复合注解。

如@SpringBootApplication组合了@Configuration、@ComponentSan、@EnnableAutoConfiguration,所以在使用SpringBoot 时我们只需要@SpringBootApplication一个注解就能开启。

(2) 属性别名
在同个注解中为同一个功能定义两个名称不一样的属性,那么这两个属性彼此互为别名,这是为了能做到顾名思义,使之达到一目了然的效果,我们可以根据需要选择一个更加贴合特定场景的名称。

5. @Component

@Component是所有受Spring 管理组件的通用形式,@Component注解可以放在类的头上,@Component不推荐使用。

四、SpringMVC相关注解

1. @Controller

对应Controller层控制层的Bean。

使用@Controller注解标识UserController之后,就表示要把UserController交给Spring容器管理,在Spring容器中会存在一个名字为"userController"的controller。

(这个名字是根据UserController类名来取的,如果@Controller不指定其value,即直接【@Controller】,则默认的bean名字为这个类的类名首字母小写;如果指定value,即【@Controller(value=“UserController”)】或者【@Controller(“UserController”)】,则使用指定的value作为bean的名字。)

2. @Scope

使用@Controller时还经常会使用 @Scope 注解。

Spring 默认scope 是单例模式(scope=“singleton”),这样只会创建一个Controller对象,每次访问都是同一Controller对象,数据不安全,例如struts2 要求每次次访问都对应不同的Controller,这时就需要用@scope注解了。

【@Scope(“prototype”)】表示将Controller的范围声明为原型scope=“prototype”),即可以利用容器的 scope="prototype"来保证每一个请求都创建一个单独的Controller来处理,避免struts中Controller的线程安全问题。

3. @Service

对应的是Service层服务层的Bean。

@Service
public class UserServiceImpl implements IUserService
    ......
}

使用@Service标注UserServiceImpl后,当Controller需要使用UserServiceImpl的实例时,就可以由Spring创建好"userService",然后注入给Controller,在Controller只需要声明一个名字叫"userService"的变量来接收由Spring注入的"userService"即可

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

同样可以直接用【@Service】,或者用【@Service(“UserService”)】告诉Spring创建UserServiceImpl的实例时,bean的名字必须叫做"UserService"。

注意,在Controller声明的"userService"变量的类型必须是"UserServiceImpl"或者是其父类"UserService",否则由于类型不一致而无法注入。

4. @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;

主要参考文章
1.https://www.cnblogs.com/szlbm/p/5512931.html
2.https://www.cnblogs.com/estellez/p/4570015.html


分享:

低价透明

统一报价,无隐形消费

金牌服务

一对一专属顾问7*24小时金牌服务

信息保密

个人信息安全有保障

售后无忧

服务出问题客服经理全程跟进