jsp网站开发如何把自横批排,做汤的网站,如何做一个自己的app,不锈钢网站建设哪家好文章目录 前言一、使用注解储存 Bean 对象1.1 配置扫描路径1.2 类注解储存 Bean 对象1.2.1 Controller#xff08;控制器存储#xff09;1.2.2 Service#xff08;服务储存#xff09;1.2.3 Repository#xff08;仓库存储#xff09;1.2.4 Component#xff08;组件储存… 文章目录 前言一、使用注解储存 Bean 对象1.1 配置扫描路径1.2 类注解储存 Bean 对象1.2.1 Controller控制器存储1.2.2 Service服务储存1.2.3 Repository仓库存储1.2.4 Component组件储存1.2.5 Configuration配置储存1.2.6 Bean 命名规则 1.3 五大类注解的作用1.3.1 为什么有这么多的注解1.3.2 类注解之间的关系 1.4 方法注解储存 Bean 对象1.4.1 Bean 注解的使用1.4.2 Bean 对象重命名 二、使用注解获取 Bean 对象2.1 Bean 对象通过注解获取的方法2.2 三种注入方法的使用2.2.1 属性注入2.2.2 Setter 注入2.2.3 构造方法注入 2.3 三种注入方法的优缺点2.4 Resource 注入2.5 Autowired 和 Resource的区别2.6 注入同一类型的多个 Bean 报错问题2.6.1 报错问题2.6.2 使用 Resource(nameXXX) 解决2.6.3 Autowired 配合使用 Qualifier 解决 前言
前面的文章详细的介绍了 Spring 对象的创建以及对 Bean 对象的存取操作但是通过配置文件注册 Bean 对象以及使用 ApplicationContext 或 BeanFactory 的方式获取 Bean 对象的操作就显得格外的复杂。因此本文主要就是详细介绍了一种更加简单的方式来实现对 Bean 对象更加简单的储存和读取操作。
在 Spring 中要想更加简单的实现对 Bean 对象的储存和使用其核心就是使用注解本文主要就是演示如何使用注解实现对 Bean 对象的存取操作。
一、使用注解储存 Bean 对象
在之前储存 Bean 对象的时候还需在 spring-congig 文件中添加一行 bean 内容才行而且每需要新增一个 Bean 对象到 Spring 容器中就需要新增一行这样的操作就显得非常麻烦了。
而现在只需要使用一个注解就能代替这一行 bean 内容此时就变得非常方便。想要通过注解的方式将对象储存到 Spring 容器中主要有两种注解类型可以实现 使用类注解五大类注解: Controller控制储存验证用户请求的数据合法性相当于安保系统Service服务储存用于编排和调度具体的执行方法Repository仓库储存持久层与数据库进行交换Component组件储存相当于工具类Configuration配置储存项目中的一些配置。 使用方法注解 Bean作用在方法上需要配合上述的类注解使用。
但在此之前还需要配置一下扫描路径。
1.1 配置扫描路径
在 spring-config.xml文件中添加如下一行记录 其含义是指定一个 base package即所有需要添加到 Spring 容器中的 Bean 对象都在 base package 所指定包或者其子包下。这里我知道的包是com.spring.demo那么就意味着如果不是此包下的 Bean 对象即使加上了注解也不会被添加到 Spring 容器中。
1.2 类注解储存 Bean 对象
1.2.1 Controller控制器存储
使用 Controller 注解储存 Bean 对象
Controller
public class StudentController1 {public void sayHi(){System.out.println(do studentController1 sayHi().);}
}使用 ApplicationContext的方式获取 Bean 对象
public static void main(String[] args) {ApplicationContext context new ClassPathXmlApplicationContext(spring-config.xml);StudentController1 studentController1 context.getBean(studentController1, StudentController1.class);studentController1.sayHi();
}关于 Bean 对象的命名规则可见后文。
1.2.2 Service服务储存
使用 Service 注解储存 Bean 对象
Service
public class StudentController2 {public void sayHi(){System.out.println(do studentController2 sayHi().);}
}获取 Bean 对象
StudentController2 studentController2 context.getBean(studentController2, StudentController2.class);1.2.3 Repository仓库存储
使用 Repository 注解储存 Bean 对象
Repository
public class StudentController3 {public void sayHi(){System.out.println(do studentController3 sayHi().);}
}获取 Bean 对象
StudentController3 studentController3 context.getBean(studentController3, StudentController3.class);1.2.4 Component组件储存
使用 Component 注解储存 Bean 对象
Component
public class StudentController4 {public void sayHi(){System.out.println(do studentController4 sayHi().);}
}获取 Bean 对象
StudentController4 studentController4 context.getBean(studentController4, StudentController4.class);1.2.5 Configuration配置储存
使用 Configuration 注解储存 Bean 对象
Configuration
public class StudentController5 {public void sayHi(){System.out.println(do studentController5 sayHi().);}
}
获取 Bean 对象
StudentController5 studentController5 context.getBean(studentController5, StudentController5.class);1.2.6 Bean 命名规则
通过上述代码可以发现在创建 Bean 对象的时候都是使用的标准 “大驼峰” 的命名方式而读取的时候 Bean 的名称则是其类名称的首字母小写即小驼峰。 但是此时创建一个 SController 类并使用注解将其添加到 Spring 容器中那么此时它的 Bean 对象的名称是什么呢根据上面代码的规律难道还是SController 吗
SController sController context.getBean(sController, SController.class);当运行程序的时候发现报错了 其意思是不存在名称为 sController 这样 Bean 对象。此时如果将其改成 SController会是正确的吗 此时发现便能正常运行了。
关于 Bean 的名称生成的源码
查找 beanname选择AnnotationBeanNameGenerator 类 继续查找 继续查找 4. 找到了源码即Introspector类下的decapitalize 方法 该方法通过检查字符串的首字母是否为大写并且第二个字符也是大写的情况下直接返回原字符串不做小写化处理。这样做是为了避免一些特殊情况下例如缩写或首字母缩写词不被误处理。
1.3 五大类注解的作用
在Spring框架中五大类常用的注解分别是Component、Controller、Service、Repository和Configuration。 Component 通用的组件注解表示类是一个Spring管理的组件Bean。 Controller 用于标识控制器类通常用于Spring MVC中处理HTTP请求和视图渲染。 Service 用于标识服务类表示该类提供一些业务逻辑处理。 Repository 用于标识仓库类表示该类用于数据访问通常与数据库交互。 Configuration 用于标识配置类表示该类包含Spring配置信息通常与Bean一起使用用于定义 Bean。
1.3.1 为什么有这么多的注解 通过上面代码的演示发现这些注解的功能都是一样的既然都是一样的为什么还需要有这么多不同的注解呢 Spring 之所以提供这么多的注解是为了更好的组织和管理应用程序的组件和依赖关系。因为每个注解都有自己特定的用途让开发人员在应用程序中能够更方便地标识和区分不同类型的类。同时也提现了程序的工程分层 其中 Controller 表示的是控制层负责与用户进行交互以及验证用户提交数据的合法性Service表示的是服务层用于编排和调度具体的执行方法相当于车站中的服务台Repository表示的是持久层负责将数据持久化储存通常需要与数据库进行交互。
以上三个层次实现了程序的工程分层同时也是 Java EE 标准分层的最核心分层。
1.3.2 类注解之间的关系 查看 Controller / Service / Repository / Configuration 等注解的源码发现 它们都是 Component 子类注解这意味着被标注为 Controller / Service / Repository / Configuration 的类也被视为Component。 另外Configuration注解是一个特殊的注解它表明该类是 Spring 的配置类用于定义 Bean 和配置应用程序的其他元素。配置类中的Bean注解用于定义 Bean。
1.4 方法注解储存 Bean 对象
首先创建一个 User 实体类
package com.spring.demo.entity;/*** 普通的用户实体类*/
public class User {private Integer uid;private String username;private String password;private Integer age;public Integer getUid() {return uid;}public void setUid(Integer uid) {this.uid uid;}public String getUsername() {return username;}public void setUsername(String username) {this.username username;}public String getPassword() {return password;}public void setPassword(String password) {this.password password;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age age;}Overridepublic String toString() {return User{ uid uid , username username \ , password password \ , age age };}
}
1.4.1 Bean 注解的使用
创建一个组件类 UserBeans并使用方法注解 Bean 将 User 类添加到 Spring 容器中
Controller
public class UserBeans {Beanpublic User getUser(){User user new User();user.setUid(1);user.setUsername(王五);user.setPassword(123456);user.setAge(18);return user;}
}注意使用方法注解 Bean 的时候需要搭配五大类注解才能生效。
获取 Bean 对象
public static void main(String[] args) {ApplicationContext context new ClassPathXmlApplicationContext(spring-config.xml);User user context.getBean(getUser, User.class);System.out.println(user);
}注意当使用方法注解Bean 的时候Bean 对象的默认名称就是其 添加到 Spring 容器中的方法名。
1.4.2 Bean 对象重命名
如果直接使用方法名作为 Bean 对象的名称例如getUser就显得非常的不合理因此往往需要对 Bean 进行改名操作。但查看Bean源码的时候可以发现其中的name或 value属性是一个数组那么就意味着可以一个 Bean 对象取多个名称。 例如 此时可通过这两个名称获取该 Bean 对象发现它们是同一个 Bean
另外需要注意的是如果对 Bean 进行了重命名则原来默认的方法名就失效了。 二、使用注解获取 Bean 对象
2.1 Bean 对象通过注解获取的方法
获取 Bean 对象也叫做对象装配即把对象取出来放到某个类当中同时也叫做对象注入。
对象注入的实现方式有以下三种 属性注入属性注入是通过在属性上使用注解实现的。常见的注解有Autowired和Resource。属性注入是在 Bean 对象的属性上直接进行注入不需要提供setter方法。 Setter 注入Setter 注入是通过在 Bean 对象的 setter 方法上使用注解实现的。这种注入方式是在调用 Bean 的 setter 方法时将依赖对象作为参数传入。 构造方法注入构造方法注入是通过在 Bean 对象的构造方法上使用注解实现的。这种注入方式是在创建 Bean 对象的时候通过构造方法参数传入依赖对象。
2.2 三种注入方法的使用
下⾯按照实际开发中的模式将 Service 类注入到 Controller 类中然后通过 main 方法获取 Controller 中的 Bean 对象。 首先创建一个 UserService 类和 UserController 类 Service
public class UserService {public void sayHi(){System.out.println(hi, userService.);}
}2.2.1 属性注入
Controller
public class UserController {// 1. 属性注入Autowiredprivate UserService userService;public void sayHi(){System.out.println(do userController sayHi().);userService.sayHi();}
}2.2.2 Setter 注入
Controller
public class UserController {// 2. setter 注入private UserService userService;Autowiredpublic void setUserService(UserService userService) {this.userService userService;}public void sayHi(){System.out.println(do userController sayHi().);userService.sayHi();}
}2.2.3 构造方法注入
Controller
public class UserController {// 3. 构造方法注入private UserService userService;// Autowiredpublic UserController(UserService userService) {this.userService userService;}public void sayHi(){System.out.println(do userController sayHi().);userService.sayHi();}
}注意如果此时只有一个构造方法则Autowired 可以省略。
2.3 三种注入方法的优缺点 属性注入 优点简洁代码量少适合对属性直接注入的情况缺点 对于必须注入的属性如果没有找到匹配的Bean会导致运行时错误兼容不好只能用于 IoC 容器没办法实现 finally 修饰的变量实现注入过于简单容易违背单一设计原则。 Setter注入 优点符合单一设计原则每个方法只能传递一个对象。 缺点 没办法实现 finally 修饰的变量实现注入使用 Setter 注入的对象可能会被修改。 构造方法注入 优点 可以实现 finally 修饰的变量实现注入注入的对象不会被改变即构造方法只能执行一次构造方法注入可以保证注入对象完全被初始化。 缺点构造方法参数较多时代码显得冗长。
2.4 Resource 注入
在进行类注入时除了可以使用 Autowired 关键字之外我们还可以使用 Resource 进行注入如下代码所示
属性注入
public class UserController {// 1. 属性注入Resourceprivate UserService userService;public void sayHi(){System.out.println(do userController sayHi().);userService.sayHi();}
}
Setter注入 Controller
public class UserController {// 2. setter 注入private UserService userService;Resourcepublic void setUserService(UserService userService) {this.userService userService;}public void sayHi(){System.out.println(do userController sayHi().);userService.sayHi();}
}
遗憾的是Resource 不支持构造方法注入
2.5 Autowired 和 Resource的区别
Autowired是 Spring 框架提供的注解而 Resource 是JSR-250规范提供的注解但是 Spring 也对其进行了支持。Autowired 默认按照类型装配 Bean如果多个类型匹配可以配合 Qualifier 注解指定具体的 Bean 名称。而 Resource 默认按照属性名进行装配可以通过 name 属性指定具体的 Bean 名称。Autowired 是 Spring 的专有注解更加灵活功能更强大。Resource 是标准的 Java 注解适用于更通用的情况Autowired 可用于 Setter 注入、构造函数注入和属性注入而 Resource 只能用于 Setter 注入和属性注入不能用于构造函数注入。
2.6 注入同一类型的多个 Bean 报错问题
当存在多个类型相同的 Bean 对象并且需要通过注解将其注入到其他 Bean 对象中时如果没有明确指定注入哪个 Bean就会导致报错。
2.6.1 报错问题
例如通过 Component 中的 UserBeans 将 User 注入到 Controller 中的 UserController 中。
首先在UserBeans 使用Bean 添加两个 User 对象到 Spring 容器中
Controller
public class UserBeans {Bean(name {user1, u1})public User getUser1(){User user new User();user.setUid(1);user.setUsername(张三);user.setPassword(123456);user.setAge(18);return user;}Bean(name user2)public User getUser2(){User user new User();user.setUid(1);user.setUsername(李四);user.setPassword(123456);user.setAge(18);return user;}
}在 UserController 中分别使用 Autowired 和 Resource注入获取 Bean 对象
Autowired 此时由于存在两个相同类型的 Bean 对象但是其名称不同所以使用Autowired注解不知道获取哪个对象。
Resource 使用Resource注解同样无法判断获取哪一个对象。 关于Autowired 和 Resource 查找 Bean 对象的顺序 Autowired首先按照类型查找然后再按照名称查找Resource首先按照名称查找然后再按照类型查找。 2.6.2 使用 Resource(name“XXX”) 解决
Controller
public class UserController {Resource(name user1)private User user;public void sayHi(){System.out.println(do userController sayHi().);}
}2.6.3 Autowired 配合使用 Qualifier 解决
Controller
public class UserController {AutowiredQualifier(value user1)private User user;public void sayHi() {System.out.println(do userController sayHi().);}
}