Spring framework

核心容器(放对象)
AoP,Abstract(AOP的实现)
Data Access
Web
test单元测试 集中测试

核心容器

IoC DI

  1. 为什么要提出控制反转这样的概念?

一旦新写了一个接口的类,那么就要new一个新的类的对象,导致耦合度高
解决方案:在程序中不主动new产生对象,转为外部提供
思想:控制反转,将对象的创建控制权转移到外部

  1. Spring怎么做的?

Spring提供IoC容器,用来充当IoC思想中的“外部”
IoC容器负责对象的创建、初始化,对象在IoC容器中统称为Bean

  1. DI(Dependency Injection)依赖注入是干什么的?

DI是IoC的一种实现方式
例:service对象依赖于dao对象运行,只生成service对象还是会报错
IoC容器发现service和dao对象都在容器里,那么IoC容器会把他们绑定(关系绑定

  1. IoC quickStart
    1. 在pom.xml中导入spring-context依赖
    2. 定义Spring管理的接口和类
    3. 在resource目录下新建spring config的xml(applicationContext.xml),并配置bean为

4. 获取IoC容器 ApplicationContext ctx = new ClassPathXmlApplicationContext(“applicationContext.xml”); 5. 获取bean BookDao bookDao = (BookDao) ctx.getBean(“bookDao”); 5. DI quickStrat Service中 new形式穿件的Dao对象再保留,提供方法(mac下的generator快捷键是control+return) 1. 删除业务层中使用new创建的Dao对象 1. 提供对应的set方法 1. 在applicationContext.xml中配置server与dao的关系, property标签表示配置当前bean的属性,
name属性表示配置哪一个具体属性,这里就是尚未实例化的 private BookDao bookDao;
ref属性表示参照哪一个bean



## Bean 1. bean基础配置 起别名 name=”service1 service2”逗号 分号或者空格分隔
Spring默认生成的对象是单例模式singleton,可以修改 scope=”prototype” 非单例。因为Spring帮助管理的对象就是可以复用的对象(表现层,业务层,数据层,工具对象都适合,不适合的是那些有状态的、有具体数值的对象) 2. bean实例化 1. 使用构造方法,但是与普通的new不同之处在于 private构造方法也能被调用—>用了反射的机制 并且是无参的构造方法 2. 使用静态工厂,配置 使用工厂中的方法 3. 实例工厂(没有静态方法,因此要实例化工厂对象)
4. 方案三的改良:使用FactoryBean java //FactoryBean public class UserDaoFactoryBean implements FactoryBean<UserDao> { public UserDao getObject() throws Exception { return new UserDaoImpl(); } public Class<?> getObjectType() { return UserDao.class; } //非单例: //public boolean isSingleton() { // return false; //} } 3. 生命周期 1.初始化容器 1. 创建对象(内存分配) 1. 执行构造方法 1. 执行属性注入(set操作) 1. 执行bean初始化方法 2.使用bean,执行业务操作
3.关闭/销毁容器,执行bean销毁方法 ## 依赖注入方式 1. setter注入 步骤1,在bean中定义引用/简单类型并提供可访问的set方法
步骤2,配置中使用property标签ref/value注入引用/简单类型数据 1. 引用类型:见quickStart 1. 基本类型➕String 不用ref,用value,不用告诉类型


  1. 构造器注入

步骤1,在bean中定义引用/简单类型并提供可访问的构造方法
步骤2,配置中使用constructor-arg标签ref/value注入引用/简单类型数据

但是这种写法使得配置文件中的name和代码 紧耦合,怎么办?
方法1: 不写name,写类型type

方法2: 不写name,写索引index

  1. DI方式选择

    1. 强制依赖用构造器,因为setter可能不注入导致null对象出现
    2. 可选依赖用setter,灵活
    3. Spring框架倡导用构造器,严谨
    4. 两者可以同时使用
    5. 自己开发模块推荐用setter注入
  2. 自动装配

    1. 按类型(常用)

保留bookDao的bean配置,但是不能有多个(一般也不会写2个实现类)
保留set方法,但是在bean配置中不再写property标签

  1. 按名称

可以有多个(要保证bookDao和实例化代码中的对象名称一样)


注意:自动装配只能用于引用类型的DI;
byType必须保证容器中相同类型的bean唯一;
byName必须保证容器中有指定名称的bean,变量名与配置耦合 不推荐;
自动装配优先级低于setter注入和构造器注入

  1. 集合注入



123
234



加载properties文件

数据库配置信息(url,admin,password等)一般写在.properties文件中
所以要在applicationContext.xml中配置
步骤:

  1. 开启context命名空间
  2. 使用context命名空间,加载指定properties文件
  3. 使用${}读取加载的属性值

容器

image.png

总结

  1. 容器相关
  2. bean相关

image.png

  1. 依赖注入相关

image.png

注解开发

@Component

在配置文件中定义

为了区分,各层命名不同
业务层(service):@Service
数据层(dao):@Repository
表现层:@Controller

纯注解开发

使用Java类代替Spring核心配置文件

步骤1. 在com.abc.config.SpringConfig.java中写:

  1. @Configuration
  2. @ComponentScan({"com.abc","xxx"})
  3. public class SpringConfig {
  4. }

步骤2. 在应用中 导入ioc容器的方式改成
ApplicationContext app = new AnnotationConfigApplicationContext(SpringConfig.class);

bean的作用范围和生命周期

在impl.java中注解为非单例
@Scope(“protopype”)

生命周期:
@PostConstruct
public void init() {
sout…
}
@PreDestory
public void destory() {
sout…
}

DI

  1. 自动装配

@Autowired 解决引用类型注入
private BookDao bookDao;

��@Qualifier 指定注入的bean的id或名称,必须配合Autowired使用(用得少)

@Value 注入简单类型

  1. 读取properties文件

@PropertySource

管理第三方bean

使用@Bean配置第三方bean
将独立的配置类加入核心配置:使用@Import注解手动加入配置到核心配置

  1. 简单类型依赖注入

直接使用配置类的成员变量
image.png

  1. 引用类型依赖注入

@Bean想要注入引用类型,只需要在形参中定义引用类型
image.png

总结: XML配置与注解配置

image.png

Spring整合MyBatis

  1. 在依赖文件中增加坐标 spring-jdbc和mybatis-spring
  2. 增加配置类MybatisConfig,其中需要调用两个第三方Bean:SqlSessionFactoryBean(需要传形参), MapperScannerConfigurer

Spring整合JUnit

  1. 在依赖文件中增加坐标 junit和spring-test
  2. @RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration(classes = SpringConfig.class)
然后要测试谁就把它自动装配
image.png

AOP

简介

比较:OOP是一种垂直纵向的继承体系
OOP不足:事务控制、权限校验、日志等场景中,纵向流程中会出现相同的子流程代码,这部分重复代码也叫横切逻辑代码
一种编程思想,在不惊动原始设计的基础上做功能增强(无侵入式功能增强)
核心概念:通知类中定义共性方法,也就是通知。把需要执行共性方法的方法定义为切入点
连接点是所有方法
把切入点和通知关系绑定,就得到了切面(Aspect描述通知与切入点的对应关系)
image.png

quickStart

  1. pom文件导依赖

org.mybatis
mybatis-spring
2.0.6


org.aspectj
aspectjweaver
1.9.9.1

  1. SpringConfig中添加@EnableAspectJAutoProxy

  2. MyAdvice.java

    1. @Component//1.告诉spring加载
    2. @Aspect//2.告诉Spring这是用来做aop的
    3. public class MyAdvice {
    4. //3.定义切入点
    5. @Pointcut("execution(void com.abc.dao.BookDao.update())")
    6. private void pt() {
    7. }
    8. //5.绑定切入点和通知
    9. @Before("pt()")
    10. //4.定义通知
    11. public void mtehod() {
    12. System.out.println(System.currentTimeMillis());
    13. }
    14. }

AOP工作流程

  1. Spring容器启动
  2. 读取所有已经配置了的切入点
  3. 初始化bean,判定bean对应的类中的方法是否匹配到任意切入点
    1. 否:生成普通普通对象 -> 获取bean,调用方法并执行
    2. 是:创建原始对象(目标对象)代理对象 -> 根据代理对象的运行模式(@Before)运行原始方法和增强内容

AOP切入点表达式

匹配任意*一个(至少一个)
.. 匹配任意数量个

AOP通知类型

  1. 前置通知 @Before(“pt”)
  2. 后置通知 @After(“pt”)
  3. 环绕通知 @Around(“pt”)

需要依赖形参
为了防止原始方法被隔离,需要在中间调用一下原始方法
需要抛异常

  1. void

image.png

  1. 有返回值 接住,然后返回 Object

image.png

  1. 返回后通知 @AfterReturning(“pt”)
  2. 抛出异常后通知 @AfterThrowing(“pt”)

总结

image.png
image.png
image.png
image.png

Spring事务管理

简介

事务:在数据层保障一系列的数据库操作同成功或同失败
Spring事务:在数据层或业务层。。。

Spring事务属性

事务角色:
Spring开启的事务叫做事务管理员
加入Spring的事务为事务协调员
image.png
传播行为:
事务协调员对事务管理员所携带事务的处理态度
@Transactional(propagation = Propagation.xxx)
是一个枚举类:
image.png