自己做服装搭配的网站,国外psd免费下载网站,请问网上有没有比较好的网站可以做照片书的呀?要求质量比较好的!,静态网页设计心得体会博主简介#xff1a;想进大厂的打工人博主主页#xff1a;xyk:所属专栏: JavaEE进阶 本篇文章将讲解如何在spring中使用注解的方式来存取Bean对象#xff0c;spring提供了多种注入对象的方式#xff0c;常见的注入方式包括 构造函数注入#xff0c;Setter 方法注入和属性… 博主简介想进大厂的打工人博主主页xyk:所属专栏: JavaEE进阶 本篇文章将讲解如何在spring中使用注解的方式来存取Bean对象spring提供了多种注入对象的方式常见的注入方式包括 构造函数注入Setter 方法注入和属性注入不同的注入方式都有优缺点下面我们来讲解一下~~ 目录 文章目录 一、使用注解方式的前提 1.1 前置工作 1.2 什么是注解 二、spring基于注解存储Bean对象 2.1 类注解方式 2.2 如何读取Bean对象 2.3 读取Bean对象时的命名规则 2.4 方法注解方式 三、基于注解获取Bean对象对象装配 3.1 属性注入 3.2 Setter方法注入 3.3 构造方法注入 3.4 三种注入方式的优缺点 缺点3设计原则问题 优点3完全初始化 优点4通用性更好 四、Resource另⼀种注⼊关键字 4.1 Autowired 和 Resource 的区别 4.2 同⼀类型多个 Bean 报错处理 一、使用注解方式的前提
1.1 前置工作
在我们使用注解方式来存储 Bean对象 的前提我们要先将配置文件写好因为在spring框架中约定大于配置既然想使用它的方式就要按照人家的规定来配置。
先在 spring-config.xml 中配置包扫描路径这样才能使注解被正确识别
?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexmlns:contenthttp://www.springframework.org/schema/contextxsi:schemaLocationhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsdcontent:component-scan base-packagecom.demo//beans 其中 base-package 中的路径对应你项目中的包名即可 也就是说即使添加了注解如果不是在配置的扫描包下的类对象也是不能被存储到 Spring 中的 pom.xml
?xml version1.0 encodingUTF-8?
project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersiongroupIdorg.example/groupIdartifactIdspring-demo1/artifactIdversion1.0-SNAPSHOT/versionpropertiesmaven.compiler.source8/maven.compiler.sourcemaven.compiler.target8/maven.compiler.target/propertiesdependenciesdependencygroupIdorg.springframework/groupIdartifactIdspring-context/artifactIdversion5.2.3.RELEASE/version/dependencydependencygroupIdorg.springframework/groupIdartifactIdspring-beans/artifactIdversion5.2.3.RELEASE/version/dependency/dependencies
/project
1.2 什么是注解
注解就是代码中的特殊标记无需在xml中配置繁琐的Bean对象代码注解可以作用在类、方法、属性上。spring 针对 Bean对象的管理提供了注解方式在 spring中注解可以分为两大类
类注解 以下四个注解都可以用来创建bean实例只是为了便于开发者清晰区分当前层。方法注解Bean
Controller表示的是业务逻辑层Service服务层Repository持久层Configuration配置层;Component组件层
为什么需要这么多个类注解呢
这是因为让程序猿看到类注解之后就能直接了解当前类的用途也是为了开发更加方便~ 在我们查看上面类注解的源码中可以发现 其实这些注解⾥⾯都有⼀个注解 Component说明它们本身就是属于 Component 的“⼦类”
二、spring基于注解存储Bean对象
2.1 类注解方式
Controller 控制器存储
Controller
public class BController {public String sayHi() {return Hi,Controler.;}
}
Service 服务存储
Service
public class StudentService {public void sayHi(){System.out.println(Hi,Service);}
}
Repository 仓库存储
Repository
public class UserRepository {public String sayHi(){return Hi,Repository;}
}
Component 组件存储
Component
public class UserComponent {public String sayHi() {return Hi,Component.;}
}
Configuration 配置存储
Configuration
public class UserConfiguration {public String sayHi(){return Hi,Configuration;}
}
2.2 如何读取Bean对象
这里以读取 BController 对象为例 由于前两个首字母都是大写的所以我们使用原类名就可以读取到相应的 JavaBean 了。 那如果我们的首字母不大写或者只有一个字母大写会发生什么
2.3 读取Bean对象时的命名规则
这个时候我们就要查询 Spring 关于 bean 存储时⽣成的命名规则了。我们可以在 Idea 中使⽤搜索关键字“beanName”可以看到以下内容。 它使⽤的是 JDK Introspector 中的 decapitalize ⽅法源码如下 public static String decapitalize(String name) {if (name null || name.length() 0) {return name;}if (name.length() 1 Character.isUpperCase(name.charAt(1)) Character.isUpperCase(name.charAt(0))){return name;}char chars[] name.toCharArray();chars[0] Character.toLowerCase(chars[0]);return new String(chars);} 如果第⼀个字⺟和第⼆个字⺟都为⼤写的情况是把 bean 的⾸字⺟也⼤写存储了其他的命名规则都是首字母小写即可默认 如果不遵守这个规则的话可是会报错的如下找不到此Bean对象 2.4 方法注解方式
类注解用于标记类为Spring Bean使用ComponentScan扫描时每个注解只会创建一个Bean对象因此在同一个ApplicationContext容器中获得的对象是同一个。
那么如果想要获取不同的对象怎么办呢 下面我们就来聊一聊方法注解~
顾名思义⽅法注解就是是放到某个⽅法上的以下是简单的代码实现需要注意的是 ⽅法注解 Bean 要配合类注解才能将对象正常的存储到 Spring 容器中
Component
public class StudentBeans {// Bean(name {s1, s2})Beanpublic Student student1() {// 伪代码构建对象Student stu new Student();stu.setId(1);stu.setName(张三);stu.setAge(18);return stu;}Beanpublic Student student2() {// 伪代码构建对象Student stu new Student();stu.setId(2);stu.setName(李四);stu.setAge(20);return stu;}}
public class App {public static void main(String[] args) {ApplicationContext context new ClassPathXmlApplicationContext(spring-config.xml);Student student context.getBean(student1,Student.class);System.out.println(student);Student student2 context.getBean(student2,Student.class);System.out.println(student2);}
} Bean默认情况下Bean name 方法名 三、基于注解获取Bean对象对象装配
获取 bean 对象也叫做对象装配是把对象取出来放到某个类中有时候也叫对象注⼊。
对象装配对象注⼊的实现⽅法以下 3 种
属性注⼊构造⽅法注⼊Setter 注⼊
不同的注入方式有不同的适用场景和优缺点。以下案例则以将 Service 类注⼊到 Controller 类中为切入点帮助大家了解三种注入方式的优缺点和区别~
3.1 属性注入
Controller
Controller
public class BController {Autowiredprivate StudentService studentService;public void sayHi() {studentService.sayHi();}
}Service
Service
public class StudentService {public void sayHi(){System.out.println(Hi,Service);}
}
此时通过如下的代码即可通过 Controller 的 sayHello() 方法调用 service 中的 sayHi() 方法。其余两种装配实现方式该部分代码等同Service 也等同就不再赘述了。
public class App {public static void main(String[] args) {ApplicationContext context new ClassPathXmlApplicationContext(spring-config.xml);BController controller context.getBean(BController,BController.class);controller.sayHi();}
} 3.2 Setter方法注入
即在 setter 方法前加上 Autowired 注解。
Controller
public class BController {private StudentService studentService;Autowiredpublic void setStudentService(StudentService studentService){this.studentService studentService;}public void sayHi() {studentService.sayHi();}
}
3.3 构造方法注入
构造⽅法注⼊是在类的构造⽅法中实现注⼊。在类中添加带有参数的构造方法Spring会根据参数类型和名称在容器中找到相应的Bean进行注入。特别地如果只有⼀个构造⽅法那么 Autowired 注解可以省略~
Controller
public class BController {private StudentService studentService;Autowiredpublic BController(StudentService studentService){this.studentService studentService;}public void sayHi() {studentService.sayHi();}
}
3.4 三种注入方式的优缺点
1.属性注入最大的优点就是实现简单、使用简单 属性注入的缺点主要包含以下 3 个
功能性问题无法注入一个不可变的对象final 修饰的对象通用性问题只能适应于 IoC 容器设计原则问题更容易违背单一设计原则。
缺点1功能性问题
使用属性注入无法注入一个不可变的对象final 修饰的对象如下图所示 原因也很简单在 Java 中 final 对象不可变要么直接赋值要么在构造方法中赋值所以当使用属性注入 final 对象时它不符合 Java 中 final 的使用规范所以就不能注入成功了。 如果要注入一个不可变的对象要怎么实现呢使用下面的构造方法注入即可。 缺点2通用性问题
使用属性注入的方式只适用于 IoC 框架容器如果将属性注入的代码移植到其他非 IoC 的框架中那么代码就无效了所以属性注入的通用性不是很好。
缺点3设计原则问题
单一设计原则 定义: 就一个类而言, 应该仅有一个引起它变化的原因。单一设计原则就是自己只负责自己的事,不需要去关心别人的事。
使用属性注入的方式因为使用起来很简单所以开发者很容易在一个类中同时注入多个对象而这些对象的注入是否有必要是否符合程序设计中的单一职责原则就变成了一个问题。 但可以肯定的是注入实现越简单那么滥用它的概率也越大所以出现违背单一设计原则的概率也越大。 注意这里强调的是违背设计原则单一职责的可能性而不是一定会违背设计原则。此处针对对象是类。
2.Setter 注入的优缺点
要说 Setter 注入有什么优点的话那么首当其冲的就是它完全符合单一职责的设计原则因为每一个 Setter 只针对一个对象。
它的缺点主要体现在以下 2 点
不能注入不可变对象final 修饰的对象注入的对象可被修改。 缺点2注入对象可被修改
Setter 注入提供了 setXXX 的方法意味着你可以在任何时候、在任何地方通过调用 setXXX 的方法来改变注入对象所以 Setter 注入的问题是被注入的对象可能随时被修改。
3. 构造方法注入的优缺点
构造方法注入是 Spring 官方从 4.x 之后推荐的注入方式。
构造方法注入相比于前两种注入方法它可以注入不可变对象并且它只会执行一次也不存在像 Setter 注入那样被注入的对象随时被修改的情况它的优点有以下 4 个
可注入不可变对象注入对象不会被修改注入对象会被完全初始化通用性更好。 优点2注入对象不会被修改
因为加了final关键字而且构造方法注入不会像 Setter 注入那样构造方法在对象创建时只会执行一次因此它不存在注入对象被随时调用修改的情况。
优点3完全初始化
因为依赖对象是在构造方法中执行的而构造方法是在对象创建之初执行的因此被注入的对象在使用之前会被完全初始化这也是构造方法注入的优点之一。
优点4通用性更好
构造方法和属性注入不同构造方法注入可适用于任何环境无论是 IoC 框架还是非 IoC 框架构造方法注入的代码都是通用的所以它的通用性更好。
四、Resource另⼀种注⼊关键字
在进⾏类注⼊时除了可以使⽤ Autowired 关键字之外我们还可以使⽤ Resource 进⾏注⼊如下代码所示
Controller
public class BController {Resourceprivate StudentService studentService;public void sayHi() {studentService.sayHi();}
}
4.1 Autowired 和 Resource 的区别
出身不同Autowired 来⾃于 Spring⽽ Resource 来⾃于 JDK 的注解使⽤时设置的参数不同相⽐于 Autowired 来说它只支持requiredResource ⽀持更多的参数设置例如name 设置根据名称获取 Bean。Autowired 可⽤于 Setter 注⼊、构造函数注⼊和属性注⼊⽽ Resource 只能⽤于 Setter 注⼊和属性注⼊不能⽤于构造函数注⼊
4.2 同⼀类型多个 Bean 报错处理
当出现以下多个 Bean返回同⼀对象类型时程序会报错如下代码所示
Component
class UserComponent {Beanpublic User user1() {User user new User();user.setId(1);user.setName(Java);return user;}Beanpublic User user2() {User user new User();user.setId(2);user.setName(MySQL);return user;}
}
在另⼀个类中获取 User 对象如下代码如下
Controller
public class UserController {// 注⼊Resourceprivate User user;public User getUser() {return user;}
}
解决同⼀个类型多个 bean 的解决⽅案有以下两个
使⽤ Resource(nameuser1) 定义。使⽤ Qualifier 注解定义名称结合Autowired
使⽤ Resource(nameXXX)
Controller
class UserController {// 注⼊Resource(name user1)private User user;public User getUser() {return user;}
}
使⽤ Qualifier
Controller
public class UserController {// 注⼊AutowiredQualifier(value user2)private User user;public User getUser() {return user;}
}
Qualifier中value可以省略~ 创作不易欢迎大家私信我一起探讨问题~