ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Spring IOC核心:Bean存储与获取详解

Spring IOC核心:Bean存储与获取详解 前言本文重点讲解IOC的概念Bean及五大类注解BeanName的规则总结和如何“生产”Bean对象希望本文对您学习Spring IOC有所帮助~概念讲解总所周知Spring是一个包含众多工具的IOC容器。容器就是装东西的工具像高中化学中的烧杯用来装水Spring这个容器则是来装对象的。IOC“invison of contorl”是IOC的全名翻译过来就是控制权反转。控制权对对象的控制权反转先前对象是我们自己new对象创建出来所以是我们控制对象现在我不想自己创建了交给Spring来创建对象这就是反转。总结就是对对象的控制权由我们转成了Spring。代码案例现实中我们造汽车是从轮子开始造的而车身依赖轮子造完轮子造车身汽车依赖车身造完车身就可以造汽车根据这个用代码实现public class NewCarExample { public static void main(String[] args) { Car car new Car(); car.run(); } /** * 汽⻋对象 */ static class Car { private Framework framework; public Car() { framework new Framework(); System.out.println(Car init....); } public void run(){ System.out.println(Car run...); } } /** * 车⾝类 */ static class Framework { private Bottom bottom; public Framework() { bottom new Bottom(); System.out.println(Framework init...); } } /** * 底盘类 */ static class Bottom {8 private Tire tire; public Bottom() { this.tire new Tire(); System.out.println(Bottom init...); } } /** * 轮胎类 */ static class Tire { // 尺⼨ private int size; public Tire(){ this.size 17; System.out.println(轮胎尺⼨ size); } } }这个代码中如果我们要修改车轮的尺寸只能手动修改代码后重新运行随着对车的需求越来越大对车的个性化需求也越来越多我们需要加工各种尺寸的车轮public class NewCarExample { public static void main(String[] args) { Car car new Car(20); car.run(); } /** * 汽车对象 */ static class Car { private Framework framework; public Car(int size) { framework new Framework(size); System.out.println(Car init....); } public void run(){ System.out.println(Car run...); } } /** * 车⾝类 */ static class Framework { private Bottom bottom; public Framework(int size) { bottom new Bottom(size); System.out.println(Framework init...); } } /** * 底盘类 */ static class Bottom { private Tire tire; public Bottom(int size) { this.tire new Tire(size); System.out.println(Bottom init...); } } /** * 轮胎类 */ static class Tire { // 尺⼨ private int size; public Tire(int size){ this.size size; System.out.println(轮胎尺⼨ size); } } }从上面的代码可以看出当最底层的代码改动之后整个调用链上的全部代码都需要修改这个时候我们需要换一下思路如果先把车的样子设计出来在设计车身车轮呢那代码就变成这样p public class IocCarExample { public static void main(String[] args) { Tire tire new Tire(20); Bottom bottom new Bottom(tire); Framework framework new Framework(bottom); Car car new Car(framework); car.run(); } static class Car { private Framework framework; public Car(Framework framework) { this.framework framework; System.out.println(Car init....); } public void run() { System.out.println(Car run...); } } static class Framework { private Bottom bottom; public Framework(Bottom bottom) { this.bottom bottom; System.out.println(Framework init...); } } static class Bottom { private Tire tire; public Bottom(Tire tire) { this.tire tire; System.out.println(Bottom init...); } } static class Tire { private int size; public Tire(int size) { this.size size; System.out.println(轮胎尺⼨ size); } } }经过上述代码如果想修改底层代码不需要整个调用链都发生改变这样就能完成代码直接的解耦从而使代码更加灵活。IOC优势上述可看出控制权发生反转之后代码的解耦性更强代码也更加灵活了。资源集中管理实现资源的可配置和易管理。降低了使用资源双方的依赖程度也就是我们说的耦合度。存储Bean对象存储在Spring中的对象叫Bean对象我们想要向上文那样让Spring来创建对象首先就要先把这个类对象存储在Spring中其实在SpringMVC阶段就已经接触到了在前后端交互中我们说Controller是给这个类打上标签让启动类加载之后Spring知道要扫描这个类其实就是把和这个类放入Spring中让Spring在加载之后创建类对象进行前后端交互所以我们才不用自己去new对象。现在我们学习其他存储Bean对象的方法。这个时候需要对上面的程序进行修改存储Bean对象分为类注解和方法注解。类注解类注解Component组件存储Controller控制层Service业务层Repository数据层Configuration配置层这五个类注解的功能都大差不差在语义上有所不同Component是其他四个类注解的共同注解所以其他四个注解相当于是Component的衍生注解。相差较大的是Controller它除了把类存储在Spring容器中之外要需要接受前端参数处理数据并返回响应。Date Component Public class User{ private String name; private int age; public void print(){ System.out.println(User : name age); } }如User这个类添加了Component这个注解相当于将这个类交由Spring管理可以不用我们自己来创建对象。其他四个注解的作用和上述代码差不多但还是建议根据这个类在代码中的作用来使用注解如处理业务的类适合Service······Bean方法注解Bean是告诉Spring调用这个方法并存储这个方法的返回值为一个Bean对象以上述创建的User类为例创建UserComponent类Component Public class UserCOmponent{ Bean public User u1(){ return new User(zhangsan,14); } }Spring通过调用s1这个方法返回User对象存储在Spring容器中。为什么在上面的代码中UserComponent这个类也需要加上Component这个注解呢因为Bean只能生效在Spring管理的类中也就是需要在五大类注解所注解的类中才能使用BeanBean还可以给方法重命名Component Public class UserCOmponent{ Bean(u2) public User u1(){ return new User(zhangsan,14); } }Bean传参要注意参数和方法名不一定要一样的名字可以不同名因为Spring不是根据名字来找而是根据类型那又有一个问题如果同时存储多个类型相同的StringSpring会怎么办当Spring查询到有两个Spring的对象会优先看哪个Spring和方法的参数重名如果重名则会传递同名的Spring如果都不同名则会报错如何取出Bean对象刚才我们讲解了如何存储Bean对象那现在我们就来讲一下要如何取出Bean对象。不知大家可还记得这一段代码SpringBootApplication public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }只要被SpringBootApplication标记的类就是启动类上面这个run方法就是我们Spring项目能启动的关键。其实这个run方法是有一个放回值的但我们要的不是这个对象而是这个类的子类ApplicationContext context SpringApplication.run(DemoApplication.class, args);ApplicationContext 是Spring的中央接口是IoC容器的化身。通俗来说ApplicationContext 是Spring的大管家负责创建配置管理所有Bean对象并控制他们的生命周期他继承自BeanFactory接口但比BeanFactory更强大是面向实际企业级应用的全功能超集。getBean()方法可以通过返回值得到我们存储在Spring中的Bean我们重点关注下面三种类型getBean(String name)参数为BeanName,但返回类型是Object需要强转类型不是很推荐getBean(ClassT)通过类型获取Bean无需强转但如果该类型有多个对象会报错getBean(String name,ClassT)既指定类型又指定BeanName最稳妥解决对象冲突问题不会报错User user(User) context.getBean(user); User user1context.getBean(User.class); User user2context.getBean(user,User.class);BeanName总结如果是用五大类注解存储lBean默认BeanName是类名的小驼峰如果类名的前两位均为大写字母则BeanName为类名本身类名BeanNameHelloControllerhelloControllerUSeControllerUSeController如果是用方法注解BeanName为方法名如果重命名了BeanName不再是方法名而是Bean重命名后的名字Component Public class UserCOmponent{ Bean(u2) public User u1(){ return new User(zhangsan,14); } }如果还是用方法名则会报异常说找不到u1这个对象当然取出Bean不止这一个方法下期我们聊聊Autowired相关知识~如果本文对您有帮助麻烦请一键三连~
返回列表