浅谈下Spring IoC和DI以及 Spring 实操

一、Spring

1. 为什么要使用Spring?

  • 解决代码耦合度高的问题

    以前的代码都是类似private IEmployeeDAO employeeDAO = new EmployeeDAOImpl();这样的代码,对象都是我们手动创建的,假如将实现类改成其它的,那就需要修改涉及到这个实现类的代码,这样大大增加了维护成本。(不符合开放-封闭原则)

  • 解决控制事务繁琐问题

    如果需要对某些业务方法进行事务管理,则需要写上开启事务、保存业务、提交事务、回滚事务等代码,假如有很多个业务方法都需要进行事务管理,则会造成大量重复代码,同时,维护上也很不方便。

  • 解决第三方框架运用太麻烦

    单纯使用MyBatis框架,则需要进行获取session对象、获取Mapper对象、执行相应SQL语句、提交事务、释放资源等,而对于使用者只关心使用的问题,而不在乎创建的问题。就比如我们需要使用手机打电话,我们关心的是直接使用手机,而不是自己造一部手机出来。

2. Spring是什么?

  • Spring是一种轻量级的 IoC、DI 和 AOP 容器的开源框架。
  • 简单地说,Spring可以帮我们创建以及管理配置好的对象设置对象的属性值,并将对象(单例)存到Spring容器中,而我们需要用的时候,直接从Spring容器取出来就可以使用。

3. Spring的优势

Spring 除了不能帮我们写业务逻辑,其余的几乎什么都能帮助我们简化开发,作用如下

  • Spring 能帮我们低侵入/低耦合地根据配置文件创建及组装对象之间的依赖关系。
  • Spring 面向切面编程能帮助我们无耦合的实现日志记录,性能统计,安全控制等。
  • Spring 能非常简单的且强大的声明式事务管理。
  • Spring 提供了与第三方数据访问框架(如Hibernate、JPA)无缝集成,且自己也提供了一套 JDBC 模板来方便数据库访问。
  • Spring 提供与第三方 Web(如 Struts1/2、JSF)框架无缝集成,且自己也提供了一套 Spring MVC 框架,来方便 Web 层搭建。
  • Spring 能方便的与如 Java Mail、任务调度、缓存框架等技术整合,降低开发难度。

4. Spring FrameWork体系


5. Spring依赖

<!-- spring上下文依赖 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.8.RELEASE</version> </dependency> <!-- spring测试依赖 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>5.0.8.RELEASE</version> <scope>test</scope> </dependency> 

二、IoC 和 DI

1. IoC

  • Inversion of Control,控制反转
  • 将在程序中手动创建对象的控制权交给 IoC 容器,由 IoC 容器进行创建对象和管理对象

2. DI

  • Dependency Injection,依赖注入
  • 创建对象过程中,将对象依赖属性(常量、对象)通过配置设置值给该对象

IoC 和 DI都是一种思想或者称为想法,而Spring是这两种思想实现之一

三、Spring 基础知识

1. BeanFactory和ApplicationContext


2. Spring 配置方式

  • XML-based configuration
  • Annotation-based configuration
  • Java-based configuration

3. Spring IoC 管理 Bean 的原理

  • 通过Resource对象加载配置文件
  • 解析配置文件和Bean元素,将id作为bean的名字,class通过反射创建bean的实例
    bean类必须存在一个无参构造器
  • 调用getBean()方法时,从容器中返回对象实例

4. XML基本配置

<context:property-placeholder location="classpath:db.properties"/> <!--
        若类名字以 FactoryBean 结尾,需要注意具体创建什么类型的对象存到容器中
        初始化和销毁方法目前只有数据源对象才会配置
    --> <bean id="唯一性" class="类全限定名" [init-method="初始化方法名" destroy-method="销毁方法名"]> <property name="属性名" value="属性值"|ref="容器中另外一个 bean 的 id 值"/> ...... </bean> ......

5. 实现 FactoryBean 接口实例化

Spring在对整个bean元素解析创建对象时,会先创建该工厂对象,但检测到这个类实现了FactoryBean接口,则会使用工厂对象调用getObject()方法创建bean对象,并把bean对象存入容器中。

集成 MyBatis 框架使用,就会配置 org.mybatis.spring.SqlSessionFactoryBean

6. Bean

  • bean的创建时机:启动 Spring 容器的时候创建所有的 bean

  • 作用域:singleton(默认)、prototype、request、session、application

  • 初始化和销毁:在配置文件中设置

    • 正常关闭容器,才会执行销毁方法

    • bean的scope为prototype时,容器只负责创建和初始化,不负责销毁。

      因为多例对象是一次性的,不需要进行保存,存放在spring容器外,如果存放在spring容器内,那么就会导致容器被这些对象占满



四、第一个 Spring 程序

  1. 新建 Maven 项目并设置编译版本及添加依赖(pom.xml)

    <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>16</maven.compiler.source> <maven.compiler.target>16</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.9</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.45</version> <scope>runtime</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.20</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.8.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>5.0.8.RELEASE</version> <scope>test</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> </dependencies> 
  2. 创建表

    CREATE TABLE `employee` (
            `id` bigint(20) NOT NULL AUTO_INCREMENT,
            `username` varchar(255) DEFAULT NULL,
            `password` varchar(255) DEFAULT NULL,
            `age` int(11) DEFAULT NULL,
            PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  3. 编写数据库四要素(db.properties)

    jdbc.driverClassName=com.mysql.jdbc.Driver
    jdbc.url=jdbc:mysql:///spring-demo jdbc.username=root
    jdbc.password=admin
  4. 编写 DAO 层代码

    public interface IEmployeeDAO { void save(String username, String password, age) throws Exception;
    }
    public class EmployeeDAOImpl implements IEmployeeDAO { private DataSource dataSource; public void setDataSource(DataSource dataSource) { this.dataSource = dataSource;
            } @Override public void save(String username, String password, age) throws Exception { @Cleanup Connection connection = dataSource.getConnection(); @Cleanup PreparedStatement ps = connection.prepareStatement("INSERT INTO employee(username, password, age) VALUES(?, ?, ?)");
                    ps.setString(1, username);
                    ps.setString(2, password);
                    ps.setInteger(3, age);
                    ps.executeUpdate();
            }
    }
  5. 编写业务层代码

    public interface IEmployeeService { void save(String username, String password, Integer age) throws Exception;
    }
    public class EmployeeServiceImpl implements IEmployeeService { private IEmployeeDAO employeeDAO; public void setemployeeDAO(IEmployeeDAO employeeDAO) { this.employeeDAO = employeeDAO;
            } @Override public void save(String username, String password, age) throws Exception {
                    employeeDAO.save(username, password, age);
            }
    }
  6. 编写 Spring 配置文件(applicationContext.xml)

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:property-placeholder location="classpath:db.properties"/> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"> <property name="driverClassName" value="${jdbc.driver}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </bean> <bean id="employeeDAO" class="cn.regex.ims.dao.impl.EmployeeDAOImpl"> <property name="dataSource" ref="dataSource"/> </bean> <bean id="employeeService" class="cn.regex.ims.service.impl.EmployeeServiceImpl"> <property name="employeeDAO" ref="employeeDAO"/> </bean> </beans> 
  7. 编写测试类(EmployeeServiceTest.java)

    @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:applicationContext.xml") public class EmployeeServiceTest { @Autowired private IEmployeeService employeeService; @Test public void save() throws Exception {
            Employee employee = new Employee();
            employee.setUsername("regex");
            employee.setPassword("123456");
            employee.setAge(15);
            employeeService.save(employee);
        }
    }
#Java##Spring##程序员#
全部评论
Spring的知识
点赞 回复 分享
发布于 2022-10-22 16:33 河南

相关推荐

整顿职场的柯基很威猛:这种不可怕,最可怕的是夹在一帮名校里的二本选手,人家才是最稳的。
点赞 评论 收藏
分享
爱看电影的杨桃allin春招:我感觉你在炫耀
点赞 评论 收藏
分享
评论
点赞
5
分享
牛客网
牛客企业服务