框架(framework):框(指其约束性)架(指其支撑性),在软件设计中指为解决一个开放性问题而 设计的具有一定约束性的支撑结构。在此结构上可以根据具体问题扩展、安插更多的组成部分,从而更 迅速和方便地构建完整的解决问题的方案。
1、框架本身一般不完整到可以解决特定问题
2、框架天生就是为扩展而设计的
3、框架里面可以为后续扩展的组件提供很多辅助性、支撑性的方便易用的实用工具(utilities), 也就是说框架时常配套了一些帮助解决某类问题的库(libraries)或工具(tools)。
如何学习框架呢?
1、知道框架能做什么
2、学习框架的语法,一般框架完成一个功能需要一定的步骤
3、框架的内部实现原理(扩展)
4、尝试实现一个框架(提升)
1.2 Spring是什么Spring官网 https://spring.io
Spring具有控制反转(IoC)和面向切面(AOP)两大核心。Java Spring 框架通过声明式方式灵活地进 行事务的管理,提高开发效率和质量。
Spring 框架还是一个超级粘合平台,除了自己提供功能外,还提供粘合其他技术 和框架的能力。
1.3 Spring的优势1.4 Spring的体系结构1、方便解耦,简化开发
2、方便集成各种优秀框架
3、降低 Java EE API 的使用难度
Spring 对 Java EE 开发中非常难用的一些 API(JDBC、JavaMail、远程调用等)都提供了封装, 使这些 API 应用的难度大大降低
4、方便程序的测试
5、AOP 编程的支持
6、声明式事务的支持
只需要通过配置就可以完成对事务的管理,而无须手动编程。
Spring 为我们提供了一站式解决方案,但Spring 是模块化的,允许咱们挑选和选择适用于项目的模块, 不需要把剩余部分也引入。
Spring 框架提供约 20 个模块,可以根据应用程序的要求来选择。
2、Spring核心之IoC控制反转 2.1 IoC的概念Ioc—Inversion of Control,即“控制反转”,不是什么技术,而是一种设计思想。
IoC 是指在程序开发中,实例的创建不再由调用者管理,而是由 Spring 容器创建,因此,控制权由程序代码转移到了 Spring 容器中,控 制权发生了反转,这就是 Spring 的 IoC 思想。
例如:Javaweb中servlet并没有new就可以使用里面的dopostdoget方法,这就是tomcat服务器创建的对象,就是这种思想
2.2 Spring入门案例 2.2.1 创建maven项目 2.2.2 pom.xml文件添加依赖和插件 2.2.3 创建一个实体类 2.3.4 创建Spring的配置文件application.xml 2.3.5 使用Spring容器创建对象 2.3.6 获取Spring容器Spring 提供了两种 IoC 容器,分别为 BeanFactory 和 ApplicationContext(BeanFactory的子类)
BeanFactory beanFactory = new XmlBeanFactory(new FileSystemResource(Spring配置文件 的名称));
ApplicationContext applicationContext=new ClassPathXmlApplicationContext(Spring配 置文件的名称);
ApplicationContext applicationContext = new FileSystemXmlApplicationContext(String configLocation);
2.3.7 通过上下文对象获取容器中的对象容器中其他API
//容器中其他API
//容器中对象的个数
int beanDefinitionCount = applicationContext.getBeanDefinitionCount();
System.out.println("容器中对象的个数:"+beanDefinitionCount);
//容器中所有对象的名字
String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
System.out.println("容器中对象的名字为:");
for (String name : beanDefinitionNames) {
System.out.println(name);
}
2.3.8 创建非自定义对象
//获取日期对象(非自定义)
Object data1 = applicationContext.getBean("data1");
System.out.println(data1);
2.3.9 bean标签的属性
public void init(){
System.out.println("--------------init--------------");
}
public void destroy(){
System.out.println("-----------------destroy--------------");
}
@Test
public void test02(){
String springConfig="application.xml";
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(springConfig);
Team team1 = (Team) applicationContext.getBean("team1");
Team team11 = (Team) applicationContext.getBean("team1");
System.out.println(team1);
System.out.println(team11);
Team team2 = (Team) applicationContext.getBean("team2");
Team team22 = (Team) applicationContext.getBean("team2");
System.out.println(team2);
System.out.println(team22);
applicationContext.close();//关闭容器
}
结果:
team-默认的构造方法 id=null,name=null,location=null --------------init-------------- com.kkb.pojo.Team@32502377 com.kkb.pojo.Team@32502377 team-默认的构造方法 id=null,name=null,location=null team-默认的构造方法 id=null,name=null,location=null com.kkb.pojo.Team@2c1b194a com.kkb.pojo.Team@4dbb42b7 -----------------destroy--------------2.3 Spring容器创建对象的方式 2.3.1 使用默认的构造方法 2.3.2 使用带参数的构造方法
public Team(Integer id, String name, String location) {
this.id = id;
this.name = name;
this.location = location;
System.out.println("team-带参数的构造方法 id="+id+",name="+name+",location="+location);
}
@Test
public void CreateTypeTest01(){
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("createType.xml");
}
结果:
team-默认的构造方法 id=null,name=null,location=null team-带参数的构造方法 id=1001,name=公牛,location=纽约 team-带参数的构造方法 id=1002,name=篮网,location=华盛顿2.3.3 使用工厂类
package com.kkb.pojo;
public class MyFactory {
public Team instanceFun(){
System.out.println("MyFactory------instanceFun");
return new Team(1003,"湖人","洛杉矶");
}
public static Team staticFun(){
System.out.println("MyFactory------staticFun");
return new Team(1004,"小牛","达拉斯");
}
public static void main(String[] args) {
MyFactory.staticFun();
MyFactory factory=new MyFactory();
factory.instanceFun();
}
}
结果:
MyFactory------staticFun team-带参数的构造方法 id=1004,name=小牛,location=达拉斯 MyFactory------instanceFun team-带参数的构造方法 id=1003,name=湖人,location=洛杉矶2.4 基于XML的DI(依赖注入)
:是组件之间依赖关系由容器在运行期决定,形象的说,即 由容器动态的将某个依赖关系注入到组件之中。依赖注入的目的并非为软件系统带来更多功能,而是为 了提升组件重用的频率,并为系统搭建一个灵活、可扩展的平台。通过依赖注入机制,我们只需要通过 简单的配置,而无需任何代码就可指定目标需要的资源,完成自身的业务逻辑,而不需要关心具体的资 源来自何处,由谁实现。
IoC 是一个概念,是一种思想,其实现方式多种多样。依赖注入就是其中用的比较多的一种方式。
Ioc和DI是同一个概念的不同角度描述。IoC是一种思想,概念,DI是实现它的手段。Spring框架使用依 赖注入实现IoC.
Spring 容器是一个超级大工厂,负责创建、管理所有的 Java 对象,这些 Java 对象被称为 Bean。 Spring 容器管理着容器中 Bean 之间的依赖关系,Spring 使用“依赖注入”的方式来管理 Bean 之间的依 赖关系。使用 IoC 实现对象之间的解耦和。
2.4.1 注入分类
2.4.1.1 通过set方法(常用)
set 注入也叫设值注入是指,通过 setter 方法传入被调用者的实例。这种注入方式简单、直观,因而在 Spring 的依赖注入中大量使用。
public void setTeamDao(TeamDao teamDao) {
this.teamDao = teamDao;
}
2.4.1.2 通过构造方法
构造注入是指,在构造调用者实例的同时,完成被调用者的实例化。使用构造器设置依赖关系。
public TeamService(TeamDao teamDao) {
this.teamDao = teamDao;
}
2.4.1.3. 自动注入
设置 autowire 属性值,为引用类型属性进行隐式自动注入(默认是不自动注入引用类型属 性)。根据 自动注入判断标准的不同,
可以分为两种:
byName:根据名称自动注入
byType: 根据类型自动注入
1、 byName
当配置文件中被调用者 bean 的 id 值与代码中调用者 bean 类的属性名相同时,可使用byName 方式,
2、 byType
配置文件中被调用者 bean 的 class 属性指定的类,要与代码中调用 者 bean 类的某引用类型属性类型同源 ⭐:只能有一个相同属性的类
2.5、基于注解实现IoC--重要
对于 DI 使用注解,将不再需要在 Spring 配置文件中声明 bean 实例。Spring 中使用注解,需要在原有 Spring 运行环境基础上再做一些改变。
2.5.1 声明Bean的注解 @Component在类上添加注解@Component表示该类创建对象的权限交给Spring容器。注解的value属性用于指定 bean的id值,value可以省略。
@Component 不指定 value 属性,bean 的 id 是类名的首字母小写。
除此之外,Spring中还提供了其他3个用于创建对象的注解:
@Repository : 用于dao实现类的的注解
@Service: 用户service实现类的注解
@Controller: 用于controller实现类的注解
@Repository,@Service,@Controller 是对@Component 注解的细化,标注不同层的对象。即持久 层对象,业务层对象,控制层对象。
2.5.2 包扫描需要在 Spring 配置文件中配置组件扫描器,用于在指定的基本包中扫描注解。如果没有报扫描,添加的 创建对象的注解不生效。
如果要扫描的包有多个,可以有以下方式扫描: 1、使用多个context:component-scan指定不同的包路径
2、指定 base-package的值使用分隔符
分隔符可以使用逗号(,)分号(;)还可以使用空格,不建议使用空格。
3、base-package是指定到父包名
但不建议使用顶级的父包,扫描的路径比较多,导致容器启动时间变慢。指定到目标包和合适的。也就 是注解所在包全路径。
2.5.3 属性注入@Vaule需要在属性上使用注解@Value,该注解的 value 属性用于指定要注入的值。使用该注解完成属性注入 时,类中无需 setter。当然,若属性有 setter,则也可将其加到 setter 上。
2.5.4 byType自动注入@Autowired需要在引用属性上使用注解@Autowired,该注解默认使用按类型自动装配 Bean 的方式。
2.5.5 byName自动注入@Autowired和@Qualifier
@Qualifier 的 value 属性用于指定要匹配 的 Bean 的 id 值。类中无需 set 方法,也可加到 set 方法上。
@Autowired 还有一个属性 required,默认值为 true,表示当匹配失败后,会终止程序运行。若将其值 设置为 false,则匹配失败,将被忽略,未匹配的属性值为 null。
2.5.6 自动注入@ResourceSpring提供了对 jdk中@Resource注解的支持。@Resource 注解既可以按名称匹配Bean,也可以按类 型匹配 Bean。默认是按名称注入。使用该注解,要求 JDK 必须是 6 及以上版本。@Resource 可在属性 上,也可在 set 方法上。
4、Spring核心之AOP 4.1 什么是AOP
AOP为Aspect Oriented Programming的缩写,意思为面向切面编程,是通过预编译方式和运行期动态 代理实现程序功能的统一维护的一种技术。
好处:
1、减少代码的重复,提高开发效率,便于维护。
2、专注核心业务的开发。
通过spring工厂自动实现将服务性代码以切面的方式加入到核心业务代码中。
4.2 AOP的实现机制-动态代理 4.2.1 什么是代理模式代理:自己不做,找人帮你做。
代理模式:在一个原有功能的基础上添加新的功能。
分类:静态代理和动态代理。
4.3静态代理 4.3.1 原有方式:核心业务和服务方法都编写在一起package com.kkb.service;
public class TeamService {
public void add(){
try {
System.out.println("开始事务");
System.out.println("TeamService---- add----");// 核心业务
System.out.println("提交事务");
} catch (Exception e) {
e.printStackTrace();
System.out.println("回滚事务");
}
}
}
4.3.2 基于类的静态代理
将服务性代码分离出来,核心业务--保存业务中只有保存功能
弊端:代理类只能代理一个类
4.3.3 基于接口的静态代理为核心业务(保存add)创建一个接口,通过接口暴露被代理的方法
要求:代理类和被代理类都实现了同一个接口
4.3.4 提取出切面代码,作为AOP接口
共有4个位置可以将切面代码编织进入核心业务代码中。
总结静态代理:
1)可以做到在不修改目标对象的功能前提下,对目标对象功能扩展。
2)缺点: 因为代理对象,需要与目标对象实现一样的接口。所以会有很多代理类,类太多。 一旦接口增加方法,目标对象与代理对象都要维护。
4.4 动态代理
静态代理:要求代理类一定存在,
动态代理:程序运行的时候,根据要被代理的对象动态生成代理类。
类型:
1、基于JDK的动态代理
2、基于CGLIB的动态代理
4.4.1 基于JDK的动态代理


