三天教你学会spring

本文详细介绍了Spring框架的核心特性,包括解决传统Web开发中的耦合问题,提供IOC和AOP功能,简化企业级开发。通过实例展示了如何创建自定义工厂、构建Maven项目以及搭建Spring环境。同时,深入讲解了依赖注入(DI)的set和构造注入,以及Bean的单例和多例管理。最后,讨论了Bean的生命周期和自动注入机制。
摘要由CSDN通过智能技术生成

三天教你学会spring

一,前言:
  • 传统的Wen开发存在硬编码所造成的程序过渡耦合,(例如,在sevice层中有Dao层的属性对象);
  • 部分JAVAEE的API 较为复杂,使用的效率低(例如JDBC的开发步骤);
  • 侵入性强,移植性差(这其实就是耦合性太高带来的,如,Dao层实现更换的话,在sevice和controller层都要在对应的代码上进行相应的更改);
二, 框架
2.1 概念:
  • Spring是一个项目管理框架 , 同时也是一套JAVAEE 解决方案;
  • Spring同时也是众优秀的设计模式的组合(工厂,单例,代理,适配器,包装器,观察者,模版,策略);
  • Spring并未代替现有的框架产品,而是对现有的框架产品进行有机整合,简化企业级开发,俗称“胶水框架”;
2.2 访问和下载:

官方网站:https://spring.io/

下载地址:http://repo.spring.io/release/org/springframework/spring/

三,spring架构组成:

spring 框架由 很多的模块组成 , 可分类为:

  • 核心技术为: 依赖注入 , 事件 , 资源 ,i18n , 验证, 数据绑定, 类型转换 ,SpEL , AOP
  • 测试: 模拟对象 , TestContext框架 , Spring MVC 测试 ,WebTestClient
  • 数据访问: 事务 , jdbc , DAO支持 ,ORM, 封送XML
  • SpringMVC 和Spring WebFlux Web框架
  • 集成: 远程处理 , JMS , JCA , JMX , 电子邮件 ,任务 ,调度 ,缓存
  • 语言: Kotlin , Groovy , 动态语言;
    在这里插入图片描述
GroupIdArtifactId说明
org.springframeworkspring-beansBeans 支持,包含 Groovy
org.springframeworkspring-aop基于代理的AOP支持
org.springframeworkspring-aspects基于AspectJ 的切面
org.springframeworkspring-context应用上下文运行时,包括调度和远程抽象
org.springframeworkspring-context-support支持将常见的第三方类库集成到 Spring 应用上下文
org.springframeworkspring-core其他模块所依赖的核心模块
org.springframeworkspring-expressionSpring 表达式语言,SpEL
org.springframeworkspring-instrumentJVM 引导的仪表(监测器)代理
org.springframeworkspring-instrument-tomcatTomcat 的仪表(监测器)代理
org.springframeworkspring-jdbc支持包括数据源设置和 JDBC 访问支持
org.springframeworkspring-jms支持包括发送/接收JMS消息的助手类
org.springframeworkspring-messaging对消息架构和协议的支持
org.springframeworkspring-orm对象/关系映射,包括对 JPA 和 Hibernate 的支持
org.springframeworkspring-oxm对象/XML 映射(Object/XML Mapping,OXM)
org.springframeworkspring-test单元测试和集成测试支持组件
org.springframeworkspring-tx事务基础组件,包括对 DAO 的支持及 JCA 的集成
org.springframeworkspring-webweb支持包,包括客户端及web远程调用
org.springframeworkspring-webmvcREST web 服务及 web 应用的 MVC 实现
org.springframeworkspring-webmvc-portlet用于 Portlet 环境的MVC实现
org.springframeworkspring-websocketWebSocket 和 SockJS 实现,包括对 STOMP 的支持
org.springframeworkspring-jclJakarta Commons Logging 日志系统

总结:spring框架的特点:

  1. 项目管理框架
  2. 对象工厂
  3. 提供了IOC/DI 过程
  4. 提供了AOP切面编程
四, 自定义工厂:
4.1 , 配置文件:
userDAO=com.qf.dao.UserDAOImpl
userService=com.qf.service.UserServiceImpl
4.2 ,工厂类:
package com.itluma.myshop.factory;

import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * 对象工厂,提供各种项目所需要的对象
 */
public class UserFactory {
    private Properties properties = new Properties();

    private Map<String, Object> container = new HashMap<>();

    public UserFactory() {
        //1.将配置文件中的所有内容读取到集合中
        InputStream resource = UserFactory.class.getResourceAsStream("/obj.properties");

        try {
            //java.lang.NullPointerException
            //key(name)=value
            properties.load(resource);//将obj.properties文件中的key=value读取到properties集合中

            //2.构造具体的实例对象
            //2.1 遍历Properties集合
            Enumeration<?> enumeration = properties.propertyNames();
            while (enumeration.hasMoreElements()) {
                //2.2 构造具体实例对象
                String beanName = (String) enumeration.nextElement();
                String classBeanName = (String) properties.get(beanName);
                //通过反射构造对象
                Class<?> aClass = Class.forName(classBeanName);
                Object objectBean = aClass.newInstance();
                container.put(beanName, objectBean);
            }

            System.out.println(container);
        } catch (IOException | ClassNotFoundException | InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    //根据beanName返回容器中的具体实例对象
    public Object getBean(String beanName) {
        return container.get(beanName);
    }
}
五,构建Maven项目:
5.1 新建项目:

在这里插入图片描述

5.2 选择Maven目录:

在这里插入图片描述

5.3 GAV 坐标:

在这里插入图片描述

六,Spring环境搭建:

什么是javaBean?

  • 必须存在一个无参的构造方法;
  • 字段需要私有化
  • 需要提供公共的get/set属性
class Person{
    private String name;//字段
    private Integer age;//字段
    
    public Person(){
        
    }
    
    public String getName(){//name属性
        return this.name;
    }
    public void setName(String name){
        this.name = name;
    }
    
    public  double getSalary(){//salary属性
        return 1.0;
    }
    
    ...
    
    
}
6.1 pom.xml中引入spring常用的依赖:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation=
         "http://maven.apache.org/POM/4.0.0 
          http://maven.apache.org/xsd/maven-4.0.0.xsd">
  
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.qf</groupId>
    <artifactId>hello-spring</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <!-- Spring常用依赖 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.1.6.RELEASE</version>
        </dependency>
    </dependencies>
</project>
6.2 创建spring配置文件:

命名无限制,约定俗成命名有:spring-context.xml、applicationContext.xml、beans.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
   
</beans>

七, spring工厂编码:

定义目标bean的类型

public class MyClass{
    public void show(){
        System.out.println("HelloWorld");
    }
}

spring-context.xml 中的 <beans >内部配置bean 标签:

<!-- 配置实例(id:“唯一标识”  class="需要被创建的目标对象全限定名") -->
<bean id="mc" class="com.qf.spring.part1.factory.MyClass" />

调用Spring工厂API(ApplicationContext接口)

public class TestFactory{
    /**
     * 程序中的对象都交由Spring的ApplicationContext工厂进行创建。
     */
    public static void main(String[] args){
        //1. 读取配置文件中所需创建的bean对象,并获得工厂对象
        ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-context.xml");
        //2. 通过id获取bean对象
		MyClass mc = (MyClass) ctx.getBean("mc");
        //3. 使用对象
		mc.show();
    }
}

八,依赖与配置文件详解:

spring 框架 包含多个模块 ,每个模块各司其职 ,可结合相关需求 引入相关依赖jar包,实现功能;

8.1 spring 依赖关系:
Spring常用功能的Jar包依赖关系

在这里插入图片描述

8.2 schema:

配置文件中的顶级标签中 包含了语义化标签的相关信息:

  • xmlns: 语义化标签所在的命名空间
  • xmlns:xsi: SMLSchema-instance 标签遵循Schema标签标准;
  • xsi:schemaLocation:xsd文件位置,用以描述标签语义、属性、取值范围等。
九, IOC(Inversion of Control ) 控制反转

Inversion of Control : 控制反转
反转了依赖关系的满足方式,由之前的自己创建依赖对象 , 到由工厂推送(变主动为被动 , 即为反转);
解决了具有相互依赖关系的组件之间的强耦合性,是的项目形态更加的稳健;

9.1 项目中强耦合问题:
public class UserDAOImpl implements UserDAO{....}
public class UserServiceImpl implements UserService {
    // !!!强耦合了UserDAOImpl!!!,使得UserServiceImpl变得不稳健!!
    private UserDAO userDAO= new UserDAOImpl();
    @Override
    public User queryUser() {
        return userDAO.queryUser();
    }
    ....
}
9.2 解决方案:
// 不引用任何一个具体的组件(实现类),在需要其他组件的位置预留存取值入口(set/get)
public class UserServiceImpl implements UserService {
    // !!!不再耦合任何DAO实现!!!,消除不稳健因素!!
    private UserDAO userDAO;
    // 为userDAO定义set/get,允许userDAO属性接收spring赋值
    //Getters And Setters
    @Override
    public User queryUser() {
        return userDAO.queryUser();
    }
    ....
}
<bean id="userDAO" class="com.qf.spring.part1.injection.UserDaoImpl"></bean>
<!-- UserServiceImpl组件 -->
<bean id="userService" class="com.qf.spring.part1.injection.UserServiceImpl">
    <!-- 由spring为userDAO属性赋值,值为id="userDAO"的bean -->
    <property name="userDAO" ref="userDAO"/>
</bean>

此时,如果需要更换其他UserDAO实现类,则UserServiceImpl不用任何改动!
则此时的UserServiceImpl组件变得更加稳健!

十,DI(Dependency Injection) 依赖注入:
10.1 概念:

在spring创建对象的同时,为其属性赋值, 被称为 依赖注入;

10.2 set注入:

创建对象时, spring工厂会通过set方法为其属性赋值;

  • 定义目标Bean类型:
@Data
public class User {
    private Integer id;
    private String password;
    private String sex;
    private Integer age;
    private Date bornDate;
    private String[] hobbys;
    private Set<String> phones;
    private List<String> names;
    private Map<String,String> countries;
    private Properties files;
    //Getters And Setters
}
  • 构建对象: 基本类型 + 字符串类型 + 日期类型
 <bean id="u1" class="com.qf.spring.part1.injection.User">
    <!--base field-->
    <property name="id" value="1001" />
    <property name="password" value="123456" />
    <property name="sex" value="male" />
    <property name="age" value="20" />
    <property name="bornDate" value="1990/1/1" /><!--注意格式"/"-->
</bean>

: 容器类型:

<bean id="u1" class="com.qf.spring.part1.injection.User">	
	<!--Array-->
    <property name="hobbys">
        <array>
            <value>Run</value>
            <value>Swim</value>
            <value>Climb</value>
        </array>
    </property>

    <!--Set-->
    <property name="phones">
        <set>
            <value>13777777777</value>
            <value>13888888888</value>
            <value>13999999999</value>
        </set>
    </property>

    <!--List-->
    <property name="names">
        <list>
            <value>tom</value>
            <value>jack</value>
            <value>marry</value>
        </list>
    </property>

    <!--Map-->
    <property name="countries">
        <map>
            <entry key="CN" value="China" />
            <entry key="US" value="America" />
            <entry key="KR" value="Korea" />
        </map>
    </property>
    
    <!--Properties-->
    <property name="files">
        <props>
            <prop key="first">One</prop>
            <prop key="second">Two</prop>
            <prop key="third">Three</prop>
        </props>
    </property>
</bean>

自建类型:

<!--次要bean,被作为属性-->
<bean id="addr" class="com.qf.spring.part1.injection.Address">
    <property name="position" value="北京市海淀区" />
    <property name="zipCode" value="100001" />
</bean>

<!--主要bean,操作的主体-->
<bean id="u2" class="com.qf.spring.part1.injection.User">
    <property name="address" ref="addr" /><!--address属性引用addr对象-->
</bean>
10.3 构造注入:

创建对象时 ,spring 工厂会 通过构造方法为对象的属性赋值;

10.3.1 定义目标Bena类型
@Data
public class Student {
    private Integer id;
    private String name;
    private String sex;
    private Integer age;
  
    //Constructors
  	public Student(Integer id , String name , String sex , Integer age){
      	this.id = id;
    	this.name = name;
  	    this.sex = sex;
	    this.age = age;
    }
}
10.3.2 注入:
 <!--构造注入-->
<bean id="u3" class="com.qf.zcg.spring.day1.t2.ioc.Student">
    <constructor-arg name="id" value="1234" /> <!-- 除标签名称有变化,其他均和Set注入一致 -->
    <constructor-arg name="name" value="tom" />
    <constructor-arg name="age" value="20" />
    <constructor-arg name="sex" value="male" />
</bean>
10.4 自动注入

不用在配置中,指定为哪个属性赋值 ,赋什么值;
有spring自动根据某个“原则”,在工厂中查找一个bean,为属性注入属性值;

public class UserServiceImpl implements UserService {
    private UserDAO userDAO;
    //Getters And Setters
    ....
}
<bean id="userDao" class="com.qf.spring.part1.injection.UserDaoImpl" />
<!-- 为UserServiceImpl中的属性基于类型自动注入值 -->
<bean id="userService" class="com.qf.spring.part1.injection.UserServiceImpl" autowire="byType"></bean>

<bean id="userDao" class="com.qf.spring.part1.injection.UserDaoImpl" />
<!-- 为UserServiceImpl中的属性基于类型自动注入值 -->
<bean id="userService" class="com.qf.spring.part1.injection.UserServiceImpl" autowire="byName"></bean>
十一,Bean细节:
11.1 控制简单对象的单例, 多例:
<!--
	singleton(默认):容器第一次启动时,构造对象。
	prototype:每次获取对象时构造对象。
-->
<bean id="mc" class="com.qf.zcg.spring.day1.t1.basic.MyClass" scope="singleton" /> 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值