Spring入门学习(超全)--实训 2019/10 / 11

学习笔记

Spring诞生:

•创建Spring的目的就是用来替代更加重量级的的企业级Java技术

简化Java的开发

◾基于POJO轻量级和最小侵入式开发

◾通过依赖注入和面向接口实现松耦合

基于切面和惯例进行声明式编程

◾通过切面和模板减少样板式代码

  • 声明Spring的基础库



	这是 Spring的 HelloWorld 例子,所以我们只使用基本的Spring库(核心)。打开pom.xml文件来将使用的库声明:


	
		
			pom.xml 使用以下内容重新覆盖原上面的内容。
		
	


	
<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.yiibai</groupId>
  <artifactId>HelloSpring</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  
  
      <dependencies>
 
        <!-- Spring Core -->
        <!-- http://mvnrepository.com/artifact/org.springframework/spring-core -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>4.1.4.RELEASE</version>
        </dependency>
         
        <!-- Spring Context -->
        <!-- http://mvnrepository.com/artifact/org.springframework/spring-context -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.1.4.RELEASE</version>
        </dependency>
         
    </dependencies>
  
</project>
	

侵入式概念

Spring是一种非侵入式的框架…

  • 侵入式

对于EJB、Struts2等一些传统的框架,通常是要实现特定的接口,继承特定的类才能增强功能

改变了java类的结构

  • 非侵入式

对于Hibernate、Spring等框架,对现有的类结构没有影响,就能够增强JavaBean的功能

松耦合

前面我们在写程序的时候,都是面向接口编程,通过DaoFactroy等方法来实现松耦合

DAO层和Service层通过DaoFactory来实现松耦合

如果Serivce层直接new DaoBook(),那么DAO和Service就紧耦合了【Service层依赖紧紧依赖于Dao】。

而Spring给我们更加合适的方法来实现松耦合,并且更加灵活、功能更加强大!---->IOC控制反转

切面编程

切面编程也就是AOP编程,其实我们在之前也接触过…动态代理就是一种切面编程了…

当时我们使用动态代理+注解的方式给Service层的方法添加权限.

@Override
    @permission("添加分类")
    /*添加分类*/
    public void addCategory(Category category) {
   
        categoryDao.addCategory(category);
    }


    /*查找分类*/
    @Override
    public void findCategory(String id) {
   
        categoryDao.findCategory(id);
    }

    @Override
    @permission("查找分类")
    /*查看分类*/
    public List<Category> getAllCategory() {
   
        return categoryDao.getAllCategory();
    }

    /*添加图书*/
    @Override
    public void addBook(Book book) {
   
        bookDao.addBook(book);

    }

*Controller调用Service的时候,Service返回的是一个代理对象

•代理对象得到Controller想要调用的方法,通过反射来看看该方法上有没有注解

•如果有注解的话,那么就判断该用户是否有权限来调用 此方法,如果没有权限,就抛出异常给Controller,Controller接收到异常,就可以提示用户没有权限了。

AOP编程可以简单理解成:在执行某些代码前,执行另外的代码

•Struts2的拦截器也是面向切面编程【在执行Action业务方法之前执行拦截器】

Spring也为我们提供更好地方式来实现面向切面编程!

引出Spring

我们试着回顾一下没学Spring的时候,是怎么开发Web项目的

在这里插入图片描述

Spring

spring是分层的轻量级java开源框架 ,为了解决企业应用开发的复杂性而创建的

主要优势:
分层框架

分层框架:
允许使用者选择用哪一个组件,提供集成框架

在这里插入图片描述

大体介绍-提供了一站式的服务

1.1、资源

官网: http://spring.io

文档: https://docs.spring.io/spring/docs/current/spring-framework-reference/、 https://github.com/waylau/spring-framework-4-reference

中文帮助: http://spring.cndocs.ml/

框架下载地址: http://repo.springsource.org/libs-release-local/org/springframework/spring/

教程: http://www.yiibai.com/spring

Git: https://github.com/spring-projects

源码: https://github.com/spring-projects/spring-framework

Jar包: https://github.com/spring-projects/spring-framework/releases

模块

1) Spring Core spring的核心功能

IOC容器, 解决对象创建及依赖关系
核心容器提供 Spring 框架的基本功能。核心容器的主要组件是 BeanFactory,它是工厂模式的实现。BeanFactory 使用控制反转(IOC) 模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。

2) Spring Web Spring对web模块的支持

  • 可以与struts整合,让struts的action创建交给spring
    - spring mvc模式
    - Web 上下文模块建立在应用程序上下文模块之上,为基于 Web 的应用程序提供了上下文。所以,Spring 框架支持与 Jakarta Struts 的集成。Web 模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。

3) Spring DAO Spring 对jdbc操作的支持
【JdbcTemplate模板工具类】

JDBC DAO 抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理和不同数据库供应商抛出的错误消息。异常层次结构简化了错误处理,并且极大地降低了需要编写的异常代码数量(例如打开和关闭连接)。Spring DAO 的面向 JDBC 的异常遵从通用的 DAO 异常层次结构。

4) Spring ORM spring对 对象关系 的支持

  • 既可以与hibernate整合,【session】
  • 也可以使用spring的对hibernate操作的封装

Spring 框架插入了若干个 ORM 框架,从而提供了 ORM 的对象关系工具,其中包括 JDO、Hibernate 和 iBatis SQL Map。所有这些都遵从 Spring 的通用事务和 DAO 异常层次结构。

5)Spring AOP 切面编程

通过配置管理特性,Spring AOP 模块直接将面向方面的编程功能集成到了 Spring 框架中。所以,可以很容易地使 Spring 框架管理的任何对象支持 AOP。Spring AOP 模块为基于 Spring 的应用程序中的对象提供了事务管理服务。通过使用 Spring AOP,不用依赖 EJB 组件,就可以将声明性事务管理集成到应用程序中。

6)Spring JEE spring 对javaEE其他模块的支持(EJB)
Spring 框架的功能可以用在任何 J2EE 服务器中,大多数功能也适用于不受管理的环境。Spring 的核心要点是:支持不绑定到特定 J2EE 服务的可重用业务和数据访问对象。毫无疑问,这样的对象可以在不同 J2EE 环境 (Web 或 EJB)、独立应用程序、测试环境之间重用。

在这里插入图片描述

在这里插入图片描述

Spring的核心思想之一:控制反转IOC和依赖注入DI

但是在 Spring 框架中创建对象的工作不再由开发者完成,而是交给 IoC 容器来创建,我们直接获取即可,整个流程完成反转,因此是控制反转。

拿到对象的几种方式:

  • Book book = new Book(); //自己创建
  • 工厂
  • 反射
  • spring IOC //别人帮我创建 ,并且给我送来

依赖的介绍

简单理解就是类A使用到了类B,这种依赖具有偶然性、临时性,是非常弱的关系。但是类B的变化会影响到类A。举个例子,如某人要过河,则人与船的关系就是依赖,人过河之后,与船的关系就解除了,因此是一种弱的连接。在代码层面,为类B作为参数被类A在某个方法中使用。

依赖注入

组件之间依赖关系由容器在运行期决定,形象的说,即由容器动态的将某个依赖关系注入到组件之中。依赖注入的目的并非为软件系统带来更多功能,而是为了提升组件重用的频率,并为系统搭建一个灵活、可扩展的平台。通过依赖注入机制,我们只需要通过简单的配置,而无需任何代码就可指定目标需要的资源,完成自身的业务逻辑,而不需要关心具体的资源来自何处,由谁实现。

控制

IoC 容器控制了对象------控制---->外部资源获取(不只是对象包括比如文件等)

反转–依赖对象的获取被反转了
  • 正依赖
    依赖反转,从字面理解就是把依赖倒过来了呗,那原来依赖正着的时候是啥样的呢?

正着的时候是上层建筑依赖下层建筑,依赖方式是在自己构造的时候把下层先构造好,比如Bird和Wing:

public class Bo {
   
    Wing wing;

    public Bo() {
   
        wing = new Wing();
    }
}

class Wing {
   
}

Main方法:Bo bo = new Bo();

这就是典型的上层依赖下层(为了更方便理解,可以直接把依赖理解为依赖构造函数),这样的坏处是如果下层的构造函数改了,增减了参数,那上层的构造函数也得加上类似的参数,那如果上层还有上层呢?就要一层一层加上去(如果这里不理解的话建议戳上面的链接看知乎原文,答主说的肥肠清晰)。唯一的好处是Main方法倒是很简洁。

  • 依赖反转
    这里按照上面的理解(为了更方便理解,可以直接把依赖理解为依赖构造函数)叫做取消依赖更合适一些,就是上层不再依赖于下层的构造函数,怎么做到的?下层直接构造好,把整个下层当做参数传进来:
public class Bo {
   
    Wing wing;

    public Bo(Wing w) {
   
        wing = w;
    }
}

class Wing {
   
}

Main方法:Wing wing = new Wing(); Bo bo = new Bo(wing);

这样做,如果Wing类构造函数加个参数,只需要改Main方法就行了,坏处是如果建筑层数很多的话,需要从低到高一个一个new,如果用到的地方很多,每次创建一个顶层对象都要这样那真的很麻烦

怎么简化构造代码?
就是把构造的代码封装起来呗,所有地方都调用封装好的方法创建顶层对象
Spring更高级一些,通过注解或配置文件的方式,你连一次都不用自己写,不用知道这个从底层要高层的链路,只需要通过注解或者xml告诉Spring这个类依赖的下层类是什么,下层类自然也有自己的依赖,Spring会自己一层一层地往下找,然后从最底层开始new,直到返回顶层建筑对象

依赖注入

IoC和DI由什么关系呢?

其实它们是同一个概念的不同角度描述,由于控制反转概念比较含糊(可能只是理解为容器控制对象这一个层面,很难让人想到谁来维护对象关系),所以2004年大师级人物Martin Fowler又给出了一个新的名字:“依赖注入”,相对IoC 而言,“依赖注入”明确描述了“被注入对象依赖IoC容器配置依赖对象”。

Spring的核心思想之一:面向切面 AOP

权限控制用Shiro安全框架

身份验证 和 授权

IOC对象创建–代码练习

使用Spring 架构要准备什么?

在这里插入图片描述

commons-logging-1.1.3.jar 日志
spring-beans-3.2.5.RELEASE.jar bean节点
spring-context-3.2.5.RELEASE.jar spring上下文节点
spring-core-3.2.5.RELEASE.jar spring核心功能
spring-expression-3.2.5.RELEASE.jar spring表达式相关表
以上是必须引入的5个jar文件
在这里插入图片描述

新建文件:
new - file --applicationContext.xml

src/applicationContext.xml

Spring框架反射 构建对象的代码原理(基础)

SpringIOC容器,是spring核心内容。
作用: 创建对象并处理对象的依赖关系
IOC容器创建对象:(使用了反射)
创建对象, 有几种方式:
1) 调用无参数构造器
2) 带参数构造器
3) 工厂创建对象
工厂类,静态方法创建对象
工厂类,非静态方法创建对象

spring 读取xml --解析–>class—>com.vo.User–>反射–>newInstance–>无参数的构造方法–>得到实例

<?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:p="http://www.springframework.org/schema/p"
    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">
	
	<!-- IOC容器的配置: 要创建的所有的对象都配置在这里
	user user=new User(): 这个搞定 就该写如何接收了
	 -->
	<bean id="user" class="com.vo.User" ></bean>
	 
</beans>      

测试1–过时的 解析xml文件方法

@Test
	public void test1(){
   
		Resource  resource = new ClassPathResource("applicationContext.xml");    //类路径                                 //资源
		 System.out.println( resource);
//未完
	}

结果

resource = class path resource [applicationContext.xml]
这只是一张图纸,并没有开始建设 即对象没有生成呢

注意:
ClassPathResource指 执行bin目录生成的文件 ,而不是src 目录下的那个

 test1 再写
	 BeanFactory factory = new XmlBeanFactory( resource);//过时了 教学用
	  User user = (User) factory.getBean("user1");
	 System.out.println( user);

报错了:
十月 10, 2019 11:48:23 上午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [applicationContext.xml]

问题出现在了初始化Bean 上, 即实体类需要一个无参构造函数.

测试2 - 相对于过时的 我们有更好的写法

效果一样 都是拿对象

接下来调用 API 获取对象,Spring 提供了两种方式来获取对象:id 或者运行时类。

(1)通过 id 获取对象

public void test2(){
   
//1.加载 spring.xml 配置文件
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
//2.通过 id 值获取对象
User user =(User)ac.getBean("user");

}

(2)通过运行时类获取对象

//1.加载 spring.xml 配置文件
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
//2.通过运行时类获取对象
User user = applicationContext.getBean(User.class);
System.out.println(user);


//此方法有一个弊端,当 spring.xml 中配置两个 Student 的 bean 
//时程序会抛出异常,
//因为此时两个 bean 都是由 Student 类生成的,
//IoC 容器无法将两个 bean 都返回,必须指定一个唯一的 bean。

如何调用含参的构造方法

<!-- 配置 student 对象 有弊端 相同名字属性无法区分 -->
<bean id="stu" class="com.southwind.entity.Student">
    <property name="id" value="1"></property>
    <property name="name" value="张三"></property>
    <property name="age" value="23"></property>
</bean>

Spring 通过调用每个属性的 setter 方法来完成属性的赋值,因此实体类必须有 setter 方法,否则加载时报错,getter 方法可省略。

<!-- 配置 student 对象 弊端修复  -->
<!-- 通过有参构造函数创建对象  -->
<!--value 是对应的值 除了使用 name 对应参数外,还可以通过下标 index 对应-->
<bean id="user2" class="cn.atcast.b_create_obj.User">

<constructor-arg index="0" type="int" value="100"></constructor-arg>

<
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值