学校的网站怎么做的,广告页面制作,广州软件开发工资怎么样,中国水电建设集团网站目录 承接上文#xff1a;详解Spring IoCDI #xff08;一#xff09;
1.IoC详解
1.1方法注解Bean
1.2方法注解要配合类注解使用
1.3定义多个对象
1.4重命名Bean
1.5扫描路径
2.DI详解
2.1DI与IoC的关系
2.2属性注入
2.3构造方法注入 2.4Setter注入
2.5 三…目录 承接上文详解Spring IoCDI 一
1.IoC详解
1.1方法注解Bean
1.2方法注解要配合类注解使用
1.3定义多个对象
1.4重命名Bean
1.5扫描路径
2.DI详解
2.1DI与IoC的关系
2.2属性注入
2.3构造方法注入 2.4Setter注入
2.5 三种注入优缺点分析
2.6Autowired存在问题
2.6.1Primary 2.6.2Qualifier
2.6.3Resource 承接上文详解Spring IoCDI 一
1.IoC详解
1.1方法注解Bean
类注解是添加到某个类上的 但是存在两个问题:
1.使⽤外部包⾥的类, 没办法添加类注解
2.⼀个类, 需要多个对象, 比如多个数据源
这种场景, 我们就需要使⽤⽅法注解Bean
代码示例 public class BeanConfig { Beanpublic User user(){User user new User();user.setName(zhangsan);user.setAge(18);return user;}}
当我们写完以上代码 尝试获取 bean 对象中的 user 时却发现 根本获取不到
SpringBootApplication
public class TestSpringTwoApplication {public static void main(String[] args) {ApplicationContext context SpringApplication.run(TestSpringTwoApplication.class,args);//从Spring上下⽂中获取对象User user context.getBean(User.class);//使⽤对象System.out.println(user);}
}执行结果如下 1.2方法注解要配合类注解使用
在 Spring 框架的设计中 ⽅法注解 Bean 要配合类注解才能将对象正常的存储到Spring 容器中
如下代码所示 Componentpublic class BeanConfig { Beanpublic User user(){User user new User();user.setName(zhangsan);user.setAge(18);return user;}}
再次执⾏以上代码 运⾏结果如下 1.3定义多个对象
多数据源的场景, 类是同⼀个, 但是配置不同, 指向不同的数据源.
Component
public class BeanConfig {Beanpublic User user1(){User user new User();user.setName(zhangsan);user.setAge(18);return user;}Beanpublic User user2(){User user new User();user.setName(lisi);user.setAge(28);return user;}}
获取对象
SpringBootApplication
public class TestSpringTwoApplication {public static void main(String[] args) {ApplicationContext context SpringApplication.run(TestSpringTwoApplication.class, args);//从Spring上下⽂中获取对象User user1 (User) context.getBean(user1);User user2 (User) context.getBean(user2);//使⽤对象System.out.println(user1);System.out.println(user2);}
}
运行结果 1.4重命名Bean
可以通过设置 name 属性给 Bean 对象进⾏重命名操作 如下代码所示
Bean(name {u1,user1})public User user1(){User user new User();user.setName(zhangsan);user.setAge(18);return user;}
此时我们使用u1就可以获取到User对象 User u1 (User) context.getBean(u1);
name{} 可以省略 如下代码所⽰ Bean({u1,user1})public User user1(){User user new User();user.setName(zhangsan);user.setAge(18);return user;}
只有⼀个名称时, {}也可以省略, 如: Bean(u1)public User user1(){User user new User();user.setName(zhangsan);user.setAge(18);return user;}
1.5扫描路径
使⽤前⾯学习的四个注解声明的bean想要⽣效 还需要被Spring扫描
通过修改项目工程的目录结构进行测试 运行结果 解释: 没有bean的名称为u1 使⽤五⼤注解声明的bean 要想⽣效, 还需要配置扫描路径, 让Spring扫描到这些注解也就是通过 ComponentScan来配置扫描路径.
ComponentScan({com.example.demo})
SpringBootApplication
public class TestSpringTwoApplication {public static void main(String[] args) {ApplicationContext context SpringApplication.run(TestSpringTwoApplication.class,args);//从Spring上下⽂中获取对象User user context.getBean(User.class);//使⽤对象System.out.println(user);}
}ComponentScan注解虽然没有显式配置但是实际已经包含在了启动类声明注解
SpringBootApplication中了默认扫描的范围是启动类所在包及其子包 2.DI详解
2.1DI与IoC的关系
DIDependency Injection依赖注入和 IoCInversion of Control控制反转有着密切的关系。 可以说 DI 是实现 IoC 的一种具体方式。 IoC 是一种设计思想强调将对象之间的控制权进行反转不再由对象自己去创建或获取其依赖而是由外部如框架来控制和管理依赖关系的创建和注入。 而 DI 则侧重于具体的将依赖对象注入到目标对象的操作它是实现 IoC 理念的重要手段之一。通过 DI依赖对象在合适的时候被准确地注入到需要它们的对象中从而体现了 IoC 的原则。 简单来说IoC 是更宏观的概念DI 是实现 IoC 的具体策略和机制。
关于依赖注⼊, Spring也给我们提供了三种⽅式:
属性注⼊(Field Injection)、构造⽅法注⼊(Constructor Injection)、Setter 注⼊(Setter Injection)
2.2属性注入 SpringBootApplicationpublic class SpringIocDemoApplication { public static void main(String[] args) { //获取Spring上下⽂对象ApplicationContext context SpringApplication.run(SpringIocDemoApplicatio //从Spring上下⽂中获取对象UserController userController (UserController) context.getBean(userCont //使⽤对象userController.sayHi(); 11 }}
属性注⼊是使用Autowired实现的 将 Service 类注⼊到 Controller 类中.
Service类的实现代码如下 import org.springframework.stereotype.Service; Servicepublic class UserService {public void sayHi() {System.out.println(Hi,UserService);}}
Controller 类的实现代码如下 Controllerpublic class UserController { //注⼊⽅法1: 属性注⼊Autowiredprivate UserService userService;public void sayHi(){System.out.println(hi,UserController...);userService.sayHi();}}
获取Controller中的sayHi方法 SpringBootApplicationpublic class SpringIocDemoApplication { public static void main(String[] args) { //获取Spring上下⽂对象ApplicationContext context SpringApplication.run(TestSpringTwoApplication.class,args);//从Spring上下⽂中获取对象UserController userController context.getBean(UserController.class);//使⽤对象userController.sayHi(); }} 运行结果为 2.3构造方法注入
构造方法注入是在类的构造方法中实现注入如下代码所示
Controller
public class UserController2 { //注⼊⽅法2: 构造⽅法private UserService userService; Autowiredpublic UserController2(UserService userService) {this.userService userService;} public void sayHi(){System.out.println(hi,UserController2...);userService.sayHi();}}
注意事项如果类只有⼀个构造⽅法 那么Autowired 注解可以省略如果类中有多个构造⽅法 那么需要添加上Autowired 来明确指定到底使⽤哪个构造⽅法。 2.4Setter注入
Setter 注⼊和属性的 Setter 方法实现类似 只不过在设置 set 方法的时候需要加上Autowired 注解 如下代码所示 Controllerpublic class UserController3 { //注⼊⽅法3: Setter⽅法注⼊private UserService userService; Autowiredpublic void setUserService(UserService userService) {this.userService userService;} public void sayHi(){System.out.println(hi,UserController3...);userService.sayHi();}}
2.5 三种注入优缺点分析
属性注⼊ 优点: 简洁 使⽤⽅便 缺点:只能⽤于 IoC 容器 并且只有在使⽤的时候才会出现 NPE 空指针异常、 不能注入⼀个Final修饰的属性 构造函数注⼊(Spring 4.X推荐) 优点:可以注⼊final修饰的属性、注⼊的对象不会被修改、依赖对象在使⽤前⼀定会被完全初始化 因为依赖是在类的构造⽅法中执⾏的 ⽽构造⽅法是在类加载阶段就会执⾏的⽅法、 通⽤性好, 构造⽅法是JDK⽀持的, 所以更换任何框架,他都是适⽤的 缺点: 注入多个对象时, 代码会比较繁琐 Setter注⼊(Spring 3.X推荐) 优点: ⽅便在类实例之后, 重新对该对象进⾏配置或者注⼊
缺点:不能注⼊⼀个Final修饰的属性、注⼊对象可能会被改变, 因为setter⽅法可能会被多次调⽤ , 就有被修改的风险.
2.6Autowired存在问题
当同⼀类型存在多个bean时, 使⽤Autowired会存在问题
Componentpublic class BeanConfig { Bean(u1)public User user1(){User user new User();user.setName(zhangsan);user.setAge(18);return user;} Beanpublic User user2() {User user new User();user.setName(lisi);user.setAge(19);return user;}} Controllerpublic class UserController { //注⼊user Autowiredprivate User user;public void sayHi(){System.out.println(hi,UserController...);userService.sayHi();System.out.println(user);}}
运行结果
报错的原因是 ⾮唯—的 Bean 对象。
Spring提供了以下几种解决⽅案
2.6.1Primary
Primary注解 当存在多个相同类型的Bean注⼊时 加上Primary注解 来确定默认的实现. Componentpublic class BeanConfig { Primary //指定该bean为默认bean的实现Bean(u1)public User user1(){User user new User();user.setName(zhangsan);user.setAge(18);return user;} Beanpublic User user2() {User user new User();user.setName(lisi);user.setAge(19);return user;}} 2.6.2Qualifier
指定当前要注⼊的bean对象。 在Qualifier的value属性中 指定注⼊的bean 的名称。 Qualifier注解不能单独使⽤ 必须配合Autowired使用 Controllerpublic class UserController {Qualifier(user2) //指定bean名称Autowiredprivate User user;public void sayHi(){System.out.println(hi,UserController...);System.out.println(user);}}
2.6.3Resource
使⽤Resource注解是按照bean的名称进⾏注⼊。通过name属性指定要注⼊的bean的名称。 Controllerpublic class UserController { Resource(name user2)private User user; public void sayHi(){System.out.println(hi,UserController...);System.out.println(user);}} Autowird 与 Resource的区别 • Autowired 是spring框架提供的注解 而Resource是JDK提供的注解 • Autowired 默认是按照类型注⼊ ⽽Resource是按照名称注⼊ . 相⽐于 Autowired 来说 Resource ⽀持更多的参数设置 例如 name 设置 根据名称获取 Bean。