php 网站301,联系导师邮件模板,营销策划公司职位,威海seo网站推广0. Spring中的五大注解 上图中就是五大类注解对应的层#xff0c;通过源码可以看到其他四个注解都基于Conponent
1. 存入 Bean
Spring既然是一个包含众多工具方法的IoC容器#xff0c;它是一个控制反转的容器#xff0c;所以就需要将Bean对象存入到容器中#xff0c;需要…0. Spring中的五大注解 上图中就是五大类注解对应的层通过源码可以看到其他四个注解都基于Conponent
1. 存入 Bean
Spring既然是一个包含众多工具方法的IoC容器它是一个控制反转的容器所以就需要将Bean对象存入到容器中需要用的时候从容器中获取Bean对象下面我们来介绍下存入Bean对象。
1.1 在 xml 中存入 Bean 对象
?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.xsd// 这句代码中, id 就是给 这个要注入的对象取个名字 class就是 要存入的 Bean 的类型是哪一个bean id user classcom.java.demo.User/bean/beans1.2 通过配置 Bean 扫描路径 类注解 实现 Bean 的存储
?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.xsd!-- 通过配置扫描路径 --content:component-scan base-packagecom.java.demo/content:component-scan/beans配置了 Bean 的扫描路径只有当前目录下的类才会被扫描是否加了类注解如果加了类注解后就会将 所有加了类注解的类 存入到 IoC 容器中。
Component
public class User {public void say(){System.out.println(Hello User...);}
}类注解存Bean需要注意几点 如果类名为大驼峰命名规则那么获取 Bean 的默认名称就是 类名首字母小写如果不满足首字母大写第二个字母小写那么 Bean 的名称就是原类名这点可以看源码知道 1.3 通过配置 Bean 扫描路径 方法注解 实现 Bean 的存储
?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.xsd!-- 通过配置扫描路径 --content:component-scan base-packagecom.java.demo/content:component-scan/beanspublic class Student {private String name;private Integer age;public String getName() {return name;}public void setName(String name) {this.name name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age age;}Overridepublic String toString() {return Student{ name name \ , age age };}
}Component
public class User {Beanpublic Student getStudent(){Student student new Student();student.setName(张三);student.setAge(18);return student;}public void say(){System.out.println(Hello User...);}
}在上述代码中我们可以通过 在方法上 加上 Bean 注解 将该方法存入到 IoC 容器中并且可以直接获取到该对象。 在使用 Bean 注解的时候需要注意几点 Bean 注解必须配合 五大类注解一块使用Bean 注解的默认命名 方法名称如果使用 Bean(“xxxx”)方式那么名称就是 xxxx 并且 Bean({“xxx”,“xxxxx”,“xxxxxx”})里面可以类似和数组一样多个名称如果Bean重命名后那么默认的方法名就没用获取Bean的时候就不能写默认方法名如果多个 Bean 使用相同的名称则不会报错只会存储第一个 Bean对象之后相同名称的不会存入会自动忽略 2. 获取 Bean
2.1 依赖查找DF
依赖查找依赖Bean的名称有两种方式一种是 ApplicationContext, 一种是 BeanFactory。这两种都是容器管理对象都可以获取到 Bean对象
2.11 ApplicationContext
public class App {public static void main(String[] args) {// 1. 获取 Spring 上下文对象ApplicationContext context new ClassPathXmlApplicationContext(spring-config.xml);// 2。获取 Bean 对象Student student (Student) context.getBean(student);System.out.println(student);}
}2.12 BeanFactory public static void main(String[] args) {// 1. 得到 spring 上下文对象BeanFactory context new XmlBeanFactory(new ClassPathResource(spring-config.xml));// 2. 获取 Bean 对象//Student student (Student)context.getBean(user);Student student (Student)context.getBean(student);System.out.println(student.toString());}2.13 Application VS BeanFactory
ApplicationContextBeanFactoryApplicationContext是BeanFactory的子类其拥有更多功能国际化支持、资源访问支持、事件传播BeanFactory是ApplicationContext的父类ApplicationContext加载Bean一次性加载所有Bean对象BeanFactory加载Bean懒加载按需加载使用一个加载一个 2.2 依赖注入DI
在 spring 中实现依赖注入的常见方式有3种
1.属性注入2.setter注入3.构造方法注入
2.21 属性注入
Controller
public class UserController {/*** 属性注入*/Autowiredprivate UserService userService;// 此处 main方法里面,必须使用依赖查找的方式先获取到UserControllerpublic static void main(String[] args) {ApplicationContext context new ClassPathXmlApplicationContext(spring-config.xml);UserController userController (UserController) context.getBean(userController);userController.userService.say();}
}属性注入
优点 实现简单、使用简单只需要在属性上加一个注解Autowired就不需要自己new一个对象直接获得注入的对象。
缺点
无法注入一个用 final 修饰的对象 因为在Java语法中final修饰的对象不可变要么一开始就赋值要么在构造方法里面赋值。而上述使用属性注入注入final修饰的对象就不符合规范所以不行。 只能适用于 IoC 容器如果将这些代码放到其他非IoC容器中那么代码就会失效设计原则更容易违背单一原则因为属性注入比较简单那么可能就会在一个类中注入多个对象这就可能不符合程序的单一职责问题。
2.22 Setter注入
Controller
public class UserController2 {private UserService userService;/*** setter注入*/Autowiredpublic void setUserService(UserService userService) {this.userService userService;}public static void main(String[] args) {ApplicationContext context new ClassPathXmlApplicationContext(spring-config.xml);UserController2 userController2 (UserController2) context.getBean(userController2);userController2.userService.say();}}优点似乎没什么优点而且比属性注入更加麻烦要说唯一可能有用的就是完全符合单一职责设计原则每个 setter 只针对一个对象。Setter注入 也适用于非IoC容器 缺点
不能注入 final 对象 由于是 Setter 注入提供了 set 方法那么注入的对象可以随时被更改
2.23 构造方法注入Spring4.x之后推荐的
Controller
public class UserController3 {private final UserService userService;/*** 构造方法注入*/// Autowired 此处如果构造方法参数只有一个的时候该注解可有可无public UserController3(UserService userService) {this.userService userService;}public static void main(String[] args) {ApplicationContext context new ClassPathXmlApplicationContext(spring-config.xml);UserController3 userController3 (UserController3) context.getBean(userController3);userController3.userService.say();}
}优点 可以注入 被final 修饰的对象 注入对象不会被更改因为是在构造方法注入的构造方法在对象创建的时候只会创建一次 注入的对象会被完全初始化 通用性会更好无论在 IoC容器 还是 非 IoC容器中都能用
缺点
写法更加复杂使用构造方法无法解决循环依赖的问题 Spring官方推荐的是构造方法的注入可以注入不可变对象通用性更好如果想要注入可变对象那么可以使用 Setter 注入。
3. 解决同一类型多个 Bean 的报错问题 上述代码可以看到报错出现了多个同一类型的多个Bean报错需要1个找到了2个。如何解决呢
1.Autowired 配合 Qualifier(value “xxx”)一起使用里面参数加方法名字2.使用Resource(name “xxxx”)
3. Resource 和 Autowired 出身不同Resource来自于JDKResource来自于Spring 支持参数不同Resource支持更多的参数 Autowired只支持一个参数设置 使用上的区别Resource不支持构造方法的注入 兼容性问题Autowired在社区版 IDEA可能会误报