当前位置: 首页> 财经> 创投人物 > 店铺装修公司_简单的ps网页设计教程_免费发布软文广告推广平台_搜索引擎优化包括哪些方面

店铺装修公司_简单的ps网页设计教程_免费发布软文广告推广平台_搜索引擎优化包括哪些方面

时间:2025/8/28 19:53:54来源:https://blog.csdn.net/2301_80055001/article/details/144795027 浏览次数:0次
店铺装修公司_简单的ps网页设计教程_免费发布软文广告推广平台_搜索引擎优化包括哪些方面

理解 IoC & DI

Spring 是包含了众多⼯具⽅法的 IoC 容器

List/Map -> 数据存储容器
Tomcat -> Web 容器
IoC 是Spring的核⼼思想——>把对象交给Spring管理
其实IoC在前⾯已经使⽤了, 在类上⾯添加 @RestController 和 @Controller 注解, 就是把这个对象交给Spring管理, Spring 框架启动时就会加载该类
IoC: Inversion of Control (控制反转), 也就是说 Spring 是⼀个"控制反转"的容器
控制反转就是控制权反转.  获得依赖对象的过程被反转了, 当需要某个对象时, 传统开发模式中需要⾃⼰通过 new 创建对象, 现在不需要再进⾏创建, 把创建对象的任务交给容器, 程序中只需要依赖注⼊ (Dependency Injection,DI)就可以了
这个容器称为:IoC容器. Spring是⼀个IoC容器, 所以有时Spring 也称为Spring 容器

IoC 介绍

开发方式的比较

传统的开发方式:例如现实生活中造车的流程

车>——>...——>框架>——>底座>——>轮胎...

现在以以上四个组分进行编写

public class Car {private Framework framework;public Car(int size){framework = new Framework(size);System.out.println("framework init...");}public void run(){System.out.println("car run...");}
}
public class Framework {private Bottom bottom;public Framework(int size){bottom = new Bottom(size);System.out.println("bottom init...");}
}
public class Bottom {private Tire tire;public Bottom(int size){tire = new Tire(size);System.out.println("tire init...");}
}
public class Tire {public Tire(int size){System.out.println("tire size:"+size);}
}
public class Main {public static void main(String[] args) {Car car1 = new Car(21);car1.run();}
}

可以理解为:

Car 依赖 Framework ,Framework 依赖 Bottom ,Bottom 依赖 Tire

相当于是根据轮胎造车子

此时代码的耦合度非常高,修改 size 会导致整条调用链上的代码都要修改——>

可以将依赖关系倒置过来:

Tire 依赖 Bottom ,Bottom 依赖  Framework,Framework 依赖 Car

此时相当于是把原来自己要创建的类,改为传递的方式。不需要在当前类中创建下级类,意味着即使下级类发生变化,当前类也不需要修改,也就对代码解耦合了

public class Car {private Framework framework;public Car(Framework framework){this.framework = framework;System.out.println("framework init...");}public void run(){System.out.println("car run...");}
}
public class Framework {private Bottom bottom;public Framework(Bottom bottom){this.bottom = bottom;System.out.println("bottom init...");}
}
public class Bottom {private Tire tire;public Bottom(Tire tire){this.tire = tire;System.out.println("tire init...");}
}
public class Tire {private int size;private String color;public Tire(int size,String color){System.out.println("tire size:"+size);}
}
public class Main {public static void main(String[] args) {Tire tire = new Tire(21,"red");Bottom bottom = new Bottom(tire);Framework framework = new Framework(bottom);Car car = new Car(framework);}
}

此时注意在每个类当中都没有创建下级类,而是将下级“传递”给当前类

在Main类中,创建给个类的对象,针对各个类的特定需求,在当前类中设置,然后将将当前类进行传递,不需要单独设置

IoC 优势 

相较于传统的方式,改进后的代码发生了 控制权翻转 ,不再是使用方创建并控制对象,而是把对象注入到当前对象中,依赖对象的控制权不再由当前对象控制

意味着即使依赖类发生变化,当前对象也不会受影响——>控制反转(IoC)

资源不由使⽤资源的双⽅管理,⽽由不使⽤资源的第三⽅管理,这可以带来很多好处。第⼀,资源集中管理,实现资源的可配置和易管理。第⼆,降低了使⽤资源双⽅的依赖程度,也就是我们说的耦合度
1. 资源集中管理: IoC容器会帮我们管理⼀些资源(对象等), 我们需要使⽤时, 只需要从IoC容器中去取就可以了
2. 我们在创建实例的时候不需要了解其中的细节, 降低了使⽤资源双⽅的依赖程度, 也就是耦合度
Spring 就是⼀种IoC容器, 帮助我们来做了这些资源管理

DI 介绍

DI: Dependency Injection(依赖注⼊)
容器在运⾏期间, 动态的为应⽤程序提供运⾏时所依赖的资源,称之为依赖注⼊
程序运⾏时需要某个资源,此时容器就为其提供这个资源
从这点来看, 依赖注⼊(DI)和控制反转(IoC)是从不同的⻆度的描述的同⼀件事情,就是指通过引⼊ IoC 容器,利⽤依赖关系注⼊的⽅式,实现对象之间的解耦
IoC 是⼀种思想,也是"⽬标", ⽽思想只是⼀种指导原则,最终还是要有可⾏的落地⽅案,⽽ DI 就属于具体的实现

IoC & DI 使用

Spring 是⼀个 IoC(控制反转)容器,作为容器, 那么它就具备两个最基础的功能:
Spring 容器 管理的主要是对象, 这些对象, 称之为"Bean". 把这些对象交由Spring管理, 由Spring来负责对象的创建和销毁. 程序只需要告诉Spring, 哪些需要存, 以及如何从Spring中取出对象

IoC 详解

IoC控制反转,就是将对象的控制权交给Spring的IOC容器,由IOC容器创建及管理对象
要把某个对象交给IOC容器管理,需要在类上添加⼀个注解
共有两类注解类型可以实现:
1. 类注解:@Controller、@Service、@Repository、@Component、@Configuration
2. ⽅法注解:@Bean

@Controller:控制层, 接收请求, 对请求进⾏处理, 并进⾏响应.

@Service:业务逻辑层, 处理具体的业务逻辑.
@Repository:数据访问层,也称为持久层. 负责数据访问操作
@Configuration:配置层. 处理项⽬中的⼀些配置信息
其实这些注解⾥⾯都有⼀个注解 @Component ,说明它们本⾝就是属于 @Component 的"⼦类"
@Component 是⼀个元注解,也就是说可以注解其他类注解,如 @Controller , @Service ,
@Repository 等. 这些注解被称为 @Component 的衍⽣注解
@Controller       表现层
@Service           业务逻辑层
@Repository      数据层

 Bean的存储 

使用@Controller存储如下:

@Controller  //将对象存储到Spring中
public class HelloController {public void sayHi(){System.out.println("Hello");}
}
@SpringBootApplication
public class DemoApplication {public static void main(String[] args) {//获取 Spring上下文 对象ApplicationContext context  = SpringApplication.run(DemoApplication.class, args);//从Spring上下文中获取对象HelloController bean = context.getBean(HelloController.class);//使用对象bean.sayHi();}
}

ApplicationContext  Spring 上下⽂
因为对象都交给 Spring 管理了,所以获取对象要从 Spring 中获取,那么就得先得到 Spring 的上下⽂
指当前的运⾏环境, 也可以看作是⼀个容器, 容器⾥存了很多内容, 这些内容是当前运⾏的环境

获取bean对象的方式

上述代码是根据类型来查找对象, 如果Spring容器中, 同⼀个类型存在多个bean的话——>
ApplicationContext 也提供了其他获取bean的⽅式, ApplicationContext 获取bean对象的功能, 是⽗
类BeanFactory提供的功能
@SpringBootApplication
public class DemoApplication {public static void main(String[] args) {ApplicationContext context  = SpringApplication.run(DemoApplication.class, args);HelloController bean = context.getBean(HelloController.class);System.out.println(bean);bean.sayHi();            //1. 根据 bean 的类型获取 beanHelloController bean2 = (HelloController) context.getBean("helloController");System.out.println(bean2);bean2.sayHi();          //2. 根据 bean 的名称获取 beanHelloController bean3 = (HelloController) context.getBean("helloController",HelloController.class);System.out.println(bean3);bean3.sayHi();          //3. 根据 bean 的名称和类型获取 bean}
}

               地址⼀样, 说明对象是⼀个

@SpringBootApplication
public class DemoApplication {public static void main(String[] args) {ApplicationContext context  = SpringApplication.run(DemoApplication.class, args);UController bean4 = (UController) context.getBean("uCtroller");System.out.println(bean4);bean4.say();
}

bean 的名称在spring容器中是唯一的

1. 默认情况下,类名首字母小写表示

2. 如果类名前两位均为大写,bean 的名称就是类名本身 

 获取bean对象, 是⽗类BeanFactory提供的功能

ApplicationContext VS BeanFactor
继承关系和功能⽅⾯来说:Spring 容器有两个顶级的接⼝:BeanFactory 和
ApplicationContext。其中 BeanFactory 提供了基础的访问容器的能⼒,⽽ ApplicationContext 属于 BeanFactory 的⼦类,它除了继承了 BeanFactory 的所有功能之外,它还拥有独特的特性,还添加了对国际化⽀持、资源访问⽀持、以及事件传播等⽅⾯的⽀持
从性能⽅⾯来说:ApplicationContext (提前加载)是⼀次性加载并初始化所有的 Bean 对象,⽽ BeanFactory (懒加载)是需要那个才去加载那个,因此更加轻量. (空间换时间)

方法注解 @Bean

类注解是添加到某个类上的, 但是存在两个问题:
1. 使⽤外部包⾥的类, 没办法添加类注解
2. ⼀个类, 需要多个对象, ⽐如多个数据源
这种场景, 我们就需要使⽤⽅法注解 @Bean

方法注解要配合类注解使用

在 Spring 框架的设计中,⽅法注解 @Bean 要配合类注解才能将对象正常的存储到 Spring 容器中

@Component
public class UserComponent {@Beanpublic UserInfo userInfo(){return new UserInfo("ming");}
}
@SpringBootApplication
public class DemoApplication {public static void main(String[] args) {ApplicationContext context  = SpringApplication.run(DemoApplication.class, args);UserInfo bean = context.getBean(UserInfo.class);System.out.println(bean);
}

定义多个对象

@Bean 注解的bean, bean的名称就是它的⽅法名

@Bean 可以针对同⼀个类, 定义多个对象

@Component
public class UserComponent {@Beanpublic UserInfo userInfo(){return new UserInfo("ming");}@Beanpublic UserInfo userInfo2(){return new UserInfo("liu");}
}
@SpringBootApplication
public class DemoApplication {public static void main(String[] args) {ApplicationContext context  = SpringApplication.run(DemoApplication.class, args);UserInfo bean = (UserInfo) context.getBean("userInfo");System.out.println(bean);UserInfo bean2 = (UserInfo) context.getBean("userInfo2");System.out.println(bean2);
}

重命名 Bean

可以通过设置 name 属性给 Bean 对象进⾏重命名操作

@Component
public class UserComponent {@Bean({"user","userInfo"})public UserInfo userInfo(){return new UserInfo("ming");}   
}
@SpringBootApplication
public class DemoApplication {public static void main(String[] args) {ApplicationContext context  = SpringApplication.run(DemoApplication.class, args);UserInfo bean = (UserInfo) context.getBean("user");System.out.println(bean);
}

name={} 可以省略
只有⼀个名称时, {}也可以省略

扫描路径

bean想要⽣效,还需要被Spring扫描
使⽤五⼤注解声明的bean,要想⽣效, 还需要配置扫描路径, 让Spring扫描到这些注解
也就是通过 @ComponentScan 来配置扫描路径

      将启动类移到 model 包中

@ComponentScan({"demo.component"})
@SpringBootApplication
public class DemoApplication {public static void main(String[] args) {ApplicationContext context  = SpringApplication.run(DemoApplication.class, args);UserInfo bean = (UserInfo) context.getBean("user");System.out.println(bean);
}

那为什么前⾯没有配置 @ComponentScan注解也可以呢?
@ComponentScan 注解虽然没有显式配置,但是实际上已经包含在了启动类声明注解
@SpringBootApplication 中了
默认扫描的范围是SpringBoot启动类所在包及其⼦包
在配置类上添加 @ComponentScan 注解, 该注解默认会扫描该类所在的包下所有的配置类
把启动类放在我们希望扫描的包的路径下, 这样我们定义的bean就都可以被扫描到

DI 详解

依赖注⼊是⼀个过程,是指IoC容器在创建Bean时, 去提供运⾏时所依赖的资源,资源指是对象

简单来说, 就是把对象取出来放到某个类的属性中

依赖注⼊也被称之为 "对象注⼊", "属性装配", 具体含义需要结合⽂章的上下⽂来理解

关于依赖注⼊, Spring提供了三种⽅式:
1. 属性注⼊(Field Injection)
2. 构造⽅法注⼊(Constructor Injection)
3. Setter 注⼊(Setter Injection)

依赖注入

属性注入

属性注⼊是使⽤ @Autowired 实现的,将 Service 类注⼊到 Controller 类中

@Service
public class UserService {public void sayHi(){System.out.println("Hello Service");}
}
@Controller
public class UserController {@Autowiredprivate UserService userService;public void sayHi(){userService.sayHi();System.out.println("Hello Controller");}
}
@SpringBootApplication
public class DemoApplication {public static void main(String[] args) {ApplicationContext context  = SpringApplication.run(DemoApplication.class, args);UserController bean = context.getBean(UserController.class);bean.sayHi();}
}

构造方法注入

构造⽅法注⼊是在类的构造⽅法中实现注⼊

@Controller
public class UserController {private UserService userService;@Autowiredpublic UserController(UserService userService){this.userService = userService;}public UserController(){}public void sayHi(){userService.sayHi();System.out.println("Hello Controller");}
}
@SpringBootApplication
public class DemoApplication {public static void main(String[] args) {ApplicationContext context  = SpringApplication.run(DemoApplication.class, args);UserController bean = context.getBean(UserController.class);bean.sayHi();}
}

如果类只有⼀个构造⽅法,那么 @Autowired 注解可以省略;如果类中有多个构造⽅法,
那么需要添加上 @Autowired 来明确指定到底使⽤哪个构造⽅法

Setter 注入

Setter 注⼊和属性的 Setter ⽅法实现类似,只不过在设置 set ⽅法的时候需要加上 @Autowired 注解
@Controller
public class UserController {private UserService userService;@Autowiredpublic void setUserService(UserService userService){this.userService = userService;}public void sayHi(){userService.sayHi();System.out.println("Hello Controller");}
}
@SpringBootApplication
public class DemoApplication {public static void main(String[] args) {ApplicationContext context  = SpringApplication.run(DemoApplication.class, args);UserController bean = context.getBean(UserController.class);bean.sayHi();}
}

方法的优缺点 

属性注⼊
优点: 简洁,使⽤⽅便
缺点:
只能⽤于 IoC 容器,如果是⾮ IoC 容器不可⽤,并且只有在使⽤的时候才会出现 NPE(空指针异常)
▪  不能注⼊⼀个Final修饰的属性
构造函数注⼊(Spring 4.X推荐)
优点:
可以注⼊final修饰的属性
注⼊的对象不会被修改
依赖对象在使⽤前⼀定会被完全初始化,因为依赖是在类的构造⽅法中执⾏的,⽽构造⽅法
是在类加载阶段就会执⾏的⽅法.
通⽤性好, 构造⽅法是JDK⽀持的, 所以更换任何框架,他都是适⽤的
缺点:
注⼊多个对象时, 代码会⽐较繁琐
Setter注⼊(Spring 3.X推荐)
优点: ⽅便在类实例之后, 重新对该对象进⾏配置或者注⼊
缺点:
不能注⼊⼀个Final修饰的属性
注⼊对象可能会被改变, 因为setter⽅法可能会被多次调⽤, 就有被修改的⻛险.

@Autowired存在问题

当同⼀类型存在多个bean时, 使⽤@Autowired会存在问题

@Service
public class UserService {@Beanpublic UserInfo userInfo1(){UserInfo userInfo = new UserInfo();userInfo.setName("ming");userInfo.setAge(18);return userInfo;}@Beanpublic UserInfo userInfo2(){UserInfo userInfo = new UserInfo();userInfo.setName("liu");userInfo.setAge(17);return userInfo;}
}
@Controller
public class UserController {@Autowiredprivate UserService userService;@Autowiredprivate UserInfo userInfo;public void sayHi(){System.out.println(userInfo);System.out.println("Hello");}
}
@SpringBootApplication
public class DemoApplication {public static void main(String[] args) {ApplicationContext context  = SpringApplication.run(DemoApplication.class, args);UserController bean = context.getBean(UserController.class);bean.sayHi();}
}

报错的原因是,⾮唯⼀的 Bean 对象

@Primary

当存在多个相同类型的Bean注⼊时,加上@Primary注解,来确定默认的实现
@Service
public class UserService {@Primary  //指定该bean为默认的bean@Beanpublic UserInfo userInfo1(){UserInfo userInfo = new UserInfo();userInfo.setName("ming");userInfo.setAge(18);return userInfo;}@Beanpublic UserInfo userInfo2(){UserInfo userInfo = new UserInfo();userInfo.setName("liu");userInfo.setAge(17);return userInfo;}
}

@Qualifier

指定当前要注⼊的bean对象。 在@Qualifier的value属性中,指定注⼊的bean的名称
@Qualifier注解不能单独使⽤,必须配合@Autowired使⽤
@Controller
public class UserController {@Autowiredprivate UserService userService;@Qualifier("userInfo1")@Autowiredprivate UserInfo userInfo;public void sayHi(){System.out.println(userInfo);System.out.println("Hello");}
}

@Resource

按照bean的名称进⾏注⼊,通过name属性指定要注⼊的bean的名称
@Controller
public class UserController {@Autowiredprivate UserService userService;@Resource(name = "userInfo2")@Autowiredprivate UserInfo userInfo;public void sayHi(){System.out.println(userInfo);System.out.println("Hello");}
}

@Autowird 与 @Resource的区别
@Autowired 是spring框架提供的注解,⽽@Resource是JDK提供的注解
@Autowired 默认是按照类型注⼊,⽽@Resource是按照名称注⼊. 相⽐于 @Autowired 来说,@Resource ⽀持更多的参数设置,例如 name 设置,根据名称获取 Bean
关键字:店铺装修公司_简单的ps网页设计教程_免费发布软文广告推广平台_搜索引擎优化包括哪些方面

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: