• Spring IOC


    一、为什么要使用Spring?

    Spring 是个java企业级应用的开源开发框架。Spring主要用来开发Java应用,但是有些扩展是针对构建J2EE平台的web应用。Spring 框架目标是简化Java企业级应用开发,并通过POJO为基础的编程模型促进良好的编程习惯。

    为什么要使用Spring?原因很简单,Spring有很多特点:

    轻量: Spring 是轻量的,基本的版本大约2MB。

    控制反转: Spring通过控制反转实现了松散耦合,对象们给出它们的依赖,而不是创建或查找依赖的对象们。

    面向切面的编程(AOP): Spring支持面向切面的编程,并且把应用业务逻辑和系统服务分开。

    容器: Spring 包含并管理应用中对象的生命周期和配置。

    MVC框架:Spring的WEB框架是个精心设计的框架,是Web框架的一个很好的替代品。

    事务管理: Spring 提供一个持续的事务管理接口,可以扩展到上至本地事务下至全局事务

    1.1、程序的耦合和解耦合

    藕合就是程序间的依赖关系。解藕就是降低程序间的依赖关系。在开发过程中应做到编译期不依赖,运行时再依赖。

    解藕思路:

    1、使用反射来创建对象,而不使用new关键字

    2、通过读取配置文件来获取要创建的对象全限定名

    问:以前写的代码有什么问题?

    创建java控制台程序

    创建Dao类

    创建service并调用Dao  

    创建测试类并调用service  

    层与层之间的关系通过new来实现调用,并且new对象时需要导入该对象所在的正确的包名,否则报错。这种关系称为耦合关系。

    二、IOC

    2.1、为什么要使用IOC?

    IOC呢,也就是控制反转,它的核心思想就是把对象的管理权交给了容器,那么,应用程序如果需要使用某个对象的实例,就可以直接从IOC容器里获取了。

    这种设计的好处就在于降低了程序中对象与对象之间的耦合性,使得程序的整个体系结构变得更加灵活。 

    2.1、IDEA中使用IOC

    第1步:创建一个普通Maven项目

    第2步:添加依赖

    在pom.xml中添加依赖

    1. <dependencies>
    2. <dependency>
    3. <groupId>org.springframeworkgroupId>
    4. <artifactId>spring-webmvcartifactId>
    5. <version>5.2.0.RELEASEversion>
    6. dependency>
    7. dependencies>

    三、切片1:通过xml使用IOC

    3.1、注入Java实体

    3.1.1、需求定义

    使用IOC实现User对象的注入 

    3.1.2、需求实现

    User.java的创建

    1. package practice.entity;
    2. public class User {
    3. private int id;
    4. private String name;
    5. private Date birth;
    6. //Get和Set方法,重写toString方法
    7. }

    beans.xml配置文件

    按图操作,将beans.xml配置文件设置成一个应用程序的上下文文件  

    注入User对象的信息

    在beans中配置User的信息,设定user的姓名等属性。

    1. "1.0" encoding="UTF-8"?>
    2. <beans xmlns="http://www.springframework.org/schema/beans"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    5. <bean id="user" class="practice.entity.User">
    6. <property name="id" value="1001">property>
    7. <property name="name" value="二哈">property>
    8. <property name="birth" ref="date_ref">property>
    9. bean>
    10. <bean id="date_ref" class="java.util.Date">bean>
    11. beans>

    创建测试类进行测试

    1. package practice;
    2. import org.springframework.context.ApplicationContext;
    3. import org.springframework.context.support.ClassPathXmlApplicationContext;
    4. import practice.entity.User;
    5. public class Test {
    6. public static void main(String[] args) {
    7. //在配置文件中获取应用程序上下文
    8. ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
    9. //从ioc容器中获取User对象,并注入到myUser中
    10. User myUser = (User) context.getBean("user");
    11. System.out.println(user.toString());
    12. }
    13. }

    四、切片2:通过注解使用IOC

    注解配置和 xml配置要实现的功能都是一样的,都是要降低程序间的耦合。只是配置的形式不一样。关于实际的开发中到底使用 xml还是注解,每家公司有着不同的使用习惯。

    4.1、知识点讲解

    4.1.1、@Component

    用于创建对象的注解

    相当于: 

    作用: 把资源让 spring 来管理。相当于在 xml 中配置一个 bean。 属性: value:指定 bean 的 id。如果不指定 value 属性,默认 bean 的 id 是当前类的类名。首字母小写。

    代码演示

    User实体类

    定义一个User实体类,通过@Component将该类的对象注入到IOC容器

    1. package practice.entity;
    2. import org.springframework.stereotype.Component;
    3. @Component
    4. //@Component("uuu")
    5. public class UserInfo {
    6. public void showUser(){
    7. System.out.println("我叫二哈,今年18岁");
    8. }
    9. }

    beans.xml配置类

    在配置类中我们通过component-scan注解扫描所有使用注解的类

    1. "1.0" encoding="UTF-8"?>
    2. <beans xmlns="http://www.springframework.org/schema/beans"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xmlns:context="http://www.springframework.org/schema/context"
    5. xsi:schemaLocation="http://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">
    6. <context:component-scan base-package="practice"/>
    7. beans>

    测试类  

    1. package practice;
    2. import org.springframework.context.ApplicationContext;
    3. import org.springframework.context.support.ClassPathXmlApplicationContext;
    4. import practice.entity.User;
    5. public class Test1 {
    6. public static void main(String[] args) {
    7. //读取Spring的核心配置文件
    8. ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
    9. //从IOC容器中获取User对象
    10. User usr = (User) ctx.getBean("userInfo");
    11. usr.showUser();
    12. }
    13. }

    4.1.2、@Component衍生的注解

    除了上面使用到的Component注解外还有几个常用的注解: @Component: 用于任意类的注入 @Repository: 用于标识在dao类上 @Service: 用于标识在Service类上 @Controller: 用于标识在控制器类上

    Ps:使用方式和@Component一样

    4.1.3、用于注入数据的注解

    相当于:

    4.1.3.1、@Autowired

    按照Bean的类型,从IOC容器中获取对象进行装配。

    代码演示

    UserInfo实体类

    1. //@Component("uuu")
    2. //@Component
    3. @Repository
    4. public class UserInfo {
    5. public void showUserInfo(){
    6. System.out.println("我叫二哈,今年18岁");
    7. }
    8. }

    UserService

    通过@Autowired注解从ioc容器获取UserInfo对象

    1. @Service
    2. //@Scope("singleton") //单例
    3. @Scope("prototype") //多例
    4. public class UserService {
    5. @Autowired
    6. //@Resource
    7. private UserInfo userInfo;
    8. public void showUser(){
    9. System.out.println("哈哈哈,我是userService");
    10. userInfo.showUserInfo();
    11. }
    12. }

    beans.xml  

    在beans.xml中开启注解扫描  

    1. "1.0" encoding="UTF-8"?>
    2. <beans xmlns="http://www.springframework.org/schema/beans"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xmlns:context="http://www.springframework.org/schema/context"
    5. xsi:schemaLocation="http://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">
    6. <context:component-scan base-package="practice"/>
    7. beans>

    测试类  

    1. package practice;
    2. import org.springframework.context.ApplicationContext;
    3. import org.springframework.context.support.ClassPathXmlApplicationContext;
    4. public class Test1 {
    5. public static void main(String[] args) {
    6. //读取Spring的核心配置文件
    7. ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
    8. //从IOC容器中获取User对象
    9. UserService userService = (UserService) ctx.getBean("userService");
    10. userService.showUser();
    11. }
    12. }

    4.1.4、@ Scope

    @ Scope注解:用于指定bean的作用范围,属性value:指定范围的取值。 常用取值:singleton(单例)、 prototype(多例)和生命周期相关,他们的作用就和在bean标签中使用init-method和destroy-methode的作用是一样的

    案例:演示单例模式

    修改service实现类

    修改service实现类

    1. @Service
    2. //@Scope("singleton") //单例
    3. @Scope("prototype") //多例
    4. public class UserService {
    5. // @Autowired
    6. @Resource
    7. private UserInfo userInfo;
    8. public void showUser(){
    9. System.out.println("哈哈哈,我是userService");
    10. userInfo.showUserInfo();
    11. }
    12. }

    修改测试类  

    1. package demo1;
    2. import org.springframework.context.ApplicationContext;
    3. import org.springframework.context.support.ClassPathXmlApplicationContext;
    4. public class Test2 {
    5. public static void main(String[] args) {
    6. ApplicationContext cxt = new ClassPathXmlApplicationContext("beans.xml");
    7. UserService userService = (UserService) cxt.getBean("userService");
    8. userService.showUser();
    9. UserService userService1 = (UserService) cxt.getBean("userService");
    10. System.out.println(userService == userService1);
    11. }
    12. }

    五、Spring5的新注解

    spring的核心配置文件除了可以用xml之外还可以使用一个java类来代替xml配置文件。如果要使用java类做为核心配置类,需要使用特定的注解,这些注解是在spring 5的版本中新加的

    5.1、@Configuration

    用于指定当前类是一个 spring 配置类,当创建容器时会从该类上加载注解。获取容器时需要使用AnnotationApplicationContext(有@Configuration 注解的类.class)。 

    5.2、@ComponentScan

    用于指定 spring 在初始化容器时要扫描的包。作用和在 spring 的 xml 配置文件中的:
    是一样的
    属性: basePackages:用于指定要扫描的包。和该注解中的 value 属性作用一样
    语法:
    @ComponentScan(basePackages = {"要扫描的包名1","要扫描的包名2",...})

    5.3、综合应用

    @Configuration和@ComponentScan的综合应用,零配置文件实现IOC

    修改之前切片2的案例

    第1步:将beans.xml配置文件删除

    第2步:添加配置文件

    使用@Configuration注解定义配置类,使用@ComponentScan注解开启注解的自动扫描

    1. package demo2;
    2. import org.springframework.context.annotation.ComponentScan;
    3. import org.springframework.context.annotation.Configuration;
    4. @Configuration
    5. @ComponentScan({"demo2"})
    6. public class SpringConfig {
    7. }

     第3步:添加要注入到ioc容器的实体

    1. package demo2;
    2. import org.springframework.stereotype.Component;
    3. @Component
    4. public class UserIntro {
    5. public void showUserInfo(){
    6. System.out.println("我叫二哈,今年18岁");
    7. }
    8. }

    第3步:修改测试类

    通过AnnotationApplicationContext获取IOC容器。

    1. package demo2;
    2. import org.springframework.context.ApplicationContext;
    3. import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    4. public class Test {
    5. public static void main(String[] args) {
    6. ApplicationContext cxt = new AnnotationConfigApplicationContext(SpringConfig.class);
    7. UserIntro intro = (UserIntro) cxt.getBean("userIntro");
    8. intro.showUserInfo();
    9. }
    10. }

  • 相关阅读:
    今年暑假不AC(贪心思路)
    2020年初全国行政区划矢量数据
    给电热水器瘦个身,让它好看更好用,云米电热水器Air2 Mini体验
    Golang 语言学习 01 包含如何快速学习一门新语言
    redis bitmap数据结构之java对等操作
    MySQL_数据库图形化界面软件_00000_00001
    Fiddler下载与安装
    迷你无人车 Gazebo 仿真
    Qt之Model/View架构
    Allegro172版本DFM规则之Copper Features
  • 原文地址:https://blog.csdn.net/magic_818/article/details/127982698