不积跬步,无以至千里;不积小流,无以成江海。
Spring学习
注解
1、如果所有的内容都配置在.xml文件中,那么.xml文件将会十分庞大;如果按需求分开.xml文件,那么.xml文件又会非常多。总之这将导致配置文件的可读性与可维护性变得很低。
2、开发中,在.java文件和.xml文件之间不断切换,是一件麻烦的事,同时这种思维上的不连贯也会降低开发的效率。
为了解决这两个问题,Spring引入了注解,通过"@XXX"的方式,让注解与Java Bean紧密结合,既大大减少了配置文件的体积,又增加了Java Bean的可读性与内聚性。
1. 声明bean的注解
吸引Spring容器的注意成为Spring 容器管理的Bean,提供了多个注解来声明Bean为Spring容器管理的Bean
@Component 没有明确角色的组件 @Service 在业务逻辑层(Service层)使用 @Repositpry 在数据访问层(dao层)使用 @Controller 用于标注控制层组件 @RestController
@Component
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Indexed public @interface Component { // 如果有返回组件名称,否则返回空字符串 String value() default ""; }
@Component作用在类上
@Component注解作用域默认为singleton
使用注解配置和类路径扫描时,被@Component注解标注的类会被Spring扫描并注册为Bean
@Component使用在不确定哪一个层的时候使用,可以作用在任何层次,把普通pojo实例化到spring容器
@Service
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Component public @interface Service { @AliasFor(annotation = Component.class) String value() default ""; }
@Service注解作用域默认为singleton
使用注解配置和类路径扫描时,被@Service注解标注的类会被Spring扫描并注册为Bean
@Service用于标注业务层组件,表示定义一个bean
@Service使用时没有传参数,Bean名称默认为当前类的类名,首字母小写
@Service(“serviceBeanId”)或@Service(value=”serviceBeanId”)使用时传参数,使用value作为Bean名字,不传参Bean名默认为当前类名,首字母小写
@Repository/@Mapper
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Component public @interface Repository { @AliasFor(annotation = Component.class) String value() default ""; }
@Repository注解作用在类上
@Repository注解作用域默认为singleton
使用注解配置和类路径扫描时,被@Reposito注解标注的类会被Spring扫描并注册为Bean
@Repository注解用于标注数据访问组件,即DAO组件
@Repository注解的作用不只是将类识别为Bean,同时它还能将所标注的类中抛出的数据访问异常封装为 Spring 的数据访问异常类型
理解:
@Repository(value="userDao")注解是告诉Spring,让Spring创建一个名字叫“userDao”的UserDaoImpl实例。
当Service需要使用Spring创建的名字叫“userDao”的UserDaoImpl实例时,就可以使用@Resource(name = "userDao")注解告诉Spring,Spring把创建好的userDao注入给Service即可。
如果在接口上@Mapper,然后再在 xml中的namespace指向mapper,那么spring就能动态生成一个Mapper的bean
@Controller
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Component public @interface Controller { @AliasFor(annotation = Component.class) String value() default ""; }
@Controller注解作用在类上
使用注解配置和类路径扫描时,被@Controller注解标注的类会被Spring扫描并注册为Bean
@Controller用于标注Web中控制层组件
@Controller标注的类负责处理由DispatcherServlet分发的请求,它把用户请求的数据经过业务处理层处理之后封装成一个Model ,然后再把该Model返回给对应的View进行展示
@Controller和@RequestMapping、@RequestParam等一些注解共同处理URL的映射
@RestController
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Controller @ResponseBody public @interface RestController { @AliasFor(annotation = Controller.class) String value() default ""; }
@RestController是一个组合注解,@RestController = @Controller + @ResponseBody
@RestController注解直接将返回的对象输出到客户端
如果返回字符串,直接返回,如果不是字符串,默认使用Jackson将对象序列化成JSON字符串后输出
2. 注入bean的注解
自动装配(依赖)Spring容器中的Bean
@Autowired @Inject @Resource
@Autowired
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Autowired { boolean required() default true; }
@Autowired注解作用在构造函数、方法、方法参数、类字段以及注解上
@Autowired注解可以实现Bean的自动注入
注意:
在使用@Autowired注解时,首先在容器中查询对应类型的bean
如果查询结果Bean刚好为一个,自动注入
如果查询结果Bean不止一个,通过@Qualifier注解指定自动装配Bean的名称
如果没有查询到对应类型的Bean,由于默认@Autowired(required=true),会抛出异常,解决方法是使用@Autoiwired(quired=false)
@Autowired(quired=true)意味着依赖是必须的
@Autowired(quired=false)等于告诉 Spring:在找不到匹配 Bean 时也不报错
@Inject
每次都要生成相应的set方法非常麻烦,现在如果我们使用javax.inject.jar
,只需要在相应类的属性上面加上@Inject
@Resource
@Resource默认按byName自动注入。如果没有找到符合的bean,则回退为一个原始类型进行进行查找,如果找到就注入。
只是指定了@Resource注解的name,则按name后的名字去bean元素里查找有与之相等的name属性的bean。
只指定@Resource注解的type属性,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常。
博客借鉴:https://blog.csdn.net/u014252478/article/details/85257564