文章目录

  • IoC——把类告诉spring,让spring在你需要的时候创建相关类的对象
  • 环境搭建
  • 创建对象的三种方式
  • 给Bean进行属性注入
  • DI(依赖注入)
  • Spring 简化 mybatis
  • AOP
    • Schema-based
  • 配置异常通知
    • AspectJ 方式步骤
    • Schema-based 方式
  • 环绕配置
  • 使用 AspectJ 方式实现
  • 代理模式
    • JDK动态代理
    • cglib动态代理
  • 使用注解
  • 自动注入
  • 加载properties文件
  • Scope属性
  • 声明式事务

IoC——把类告诉spring,让spring在你需要的时候创建相关类的对象

  • 中文名称:控制反转
  • 英文名称:(Inversion of Control)
  • IoC 完成的事情:原先由程序员主动通过 new 实例化对象事情,转交给 Spring 负责.
  • 控制反转中控制指的是:控制类的对象.
  • 控制反转中反转指的是转交给 Spring 负责.
  • IoC 最大的作用:解耦.
  • 程序员不需要管理对象.解除了对象管理和程序员之间的耦合.

环境搭建

  • 导入jar包,四个核心包一个日志包(commons-logging)
  • 在 src 下新建 applicationContext.xml,告诉自己配置信息最后都存到了ApplicationContext容器下。
  • spring配置文件基于schema(.xsd文件)DTD升级版(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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="user" class="com.xs.pojo.User"></bean>
</beans>

getBeanDefinitionNames()
在xml文件加载时就被创建

     ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");User user = ac.getBean("user", User.class);System.out.println(user);

创建对象的三种方式

通过构造方法创建:

    <bean id="user" class="com.xs.pojo.User"><constructor-arg name="age" value="12"></constructor-arg><constructor-arg name="id" value="4"></constructor-arg><constructor-arg name="name" value="makka"></constructor-arg></bean>
  • 如果条件匹配多个构造方法,则默认为最后一个构造方法
  • name——属性名
  • value、ref——属性值,ref为需要引用别的类
  • index——参数索引
  • type——参数类型

实例工厂和静态工厂

    <bean id="factory" class="com.xs.pojo.UserFactory"></bean><bean id="user1" factory-bean="factory" factory-method="newInstance"></bean><bean id="user2" class="com.xs.pojo.UserFactory" factory-method="newInstance"></bean>

给Bean进行属性注入

    <bean id="user3" class="com.xs.pojo.User"><property name="age" value="1"></property><property name="id" value="2"></property><property name="name" value="333"></property></bean>

普通属性通过<property>+ value

        <property name="set"><set ><value>1</value><value>2</value><value>3</value><value>0</value></set></property><property name="list"><list><value>makka</value><value>Iggle</value><value>Pakka</value></list></property><property name="map"><map><entry key="lo" value="Q"></entry><entry key="v" value="S"></entry><entry key="e" value="H"></entry></map></property>

map、set、list
数组用<array>+ value

  • 当属性为Properties时使用<property>+<props>,由于property是以键值对存储信息,所以为<prop key="key1">value1</prop>形式。

DI(依赖注入)

  • 和Ioc类似
  • 当一个类中需要另一个类时,把另一个类的对象赋值给它的过程就叫做依赖注入。
    <bean id="user4" class="com.xs.pojo.User"><property name="c" ref="computer"></property></bean><bean id="computer" class="com.xs.pojo.Computer"><property name="num" ><value>1</value></property></bean>

注意ref 和 id

Spring 简化 mybatis

1、代替dataSource功能

    <environments default="default"><!-- 声明可以使用的环境 --><environment id="default"><transactionManager type="JDBC"></transactionManager><dataSource type="POOLED"><property name="driver" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/test"/><property name="username" value="root"/><property name="password" value="000000"/></dataSource></environment></environments>
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"><property name="url" value="jdbc:mysql://localhost:3306/test"></property><property name="username" value="root"></property><property name="password" value="000000"></property><property name="driverClassName" value="com.mysql.jdbc.Driver"></property></bean>

bean 中 class 为创建对象类型,property 为其注入相关信息(本质调用set方法)

2、需要SqlSessionFactory

    <bean id="factory" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" ref="dataSource"></property></bean>

3、需要<mappers>

    <mappers><package name="com/xs/mapper"/></mappers>
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"><property name="basePackage" value="com.xs.mapper"></property><property name="sqlSessionFactory" ref="factory"></property></bean>
  • 需要扫描的包、和factory产生联系,让factory中有扫描的包。
  • 扫描完成后为对应接口创建对象(把对应接口的对象也告诉了spring)

4、配置独特的serviceImpl

public class UserServiceImpl implements UserService {private UserMapper mapper;public UserMapper getMapper() {return mapper;}public void setMapper(UserMapper mapper) {this.mapper = mapper;}@Overridepublic List<User> show() {return mapper.selAll();}
}

由于扫描包完成后 UserMapper的对象已经在spring中,所以此时将UserServiceImpl类放到<bean>标签下并为其注入 创建好的uerMapper对象,让它由spring管理。

    <bean id="userServiceImpl" class="com.xs.service.impl.UserServiceImpl"><property name="mapper" ref="userMapper"></property></bean>

5、在tomcat启动时加载配置文件
spring封装了一个监听器 (在spring-web下),将其配置在 web.xml 下

    <listener><listener-class>org.springframework.web.context.ContextCleanupListener</listener-class></listener>

当我们在web.xml中配置这个类时 tomcat 会帮我们实例化这个类,但tomcat还需要一个上下文参数。

    <context-param><param-name>contextConfigLocation</param-name><param-value>classpath:applicationContext.xml</param-value></context-param>

tomcat把取到的信息存放在 webApplicationContext ,所以要从其中取出service。

    @Overridepublic void init(ServletConfig config) throws ServletException {ApplicationContext ac = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());service = ac.getBean("userServiceImpl", UserServiceImpl.class);}

AOP

Aspect Oriented Programming

对一个或多个方法添加前置通知和后置通知形成横切面。

高扩展性 且 提高逻辑性

  • 原有功能: 切点, pointcut
  • 前置通知: 在切点之前执行的功能. before advice
  • 后置通知:在切点之后执行的功能,after advice
  • 如果切点执行过程中出现异常,会触发异常通知.throws advice
  • 所有功能总称叫做切面.
  • 两种实现方式——AspectJ、Schema-based

Schema-based

1、导入jar包

2、新建通知类

前置通知:

  • arg0:切点方法对象 Method 对象
  • arg1:切点方法参数
  • arg2:切点在哪个对象中

后置通知:

  • arg0:切点方法返回值
  • arg1:切点方法 Method对象
  • arg2:切点方法参数
  • arg3:切点方法所在对象
public class MyBeforeAdvice implements MethodBeforeAdvice {@Overridepublic void before(Method method, Object[] objects, Object o) throws Throwable {System.out.println("前置前置");}
}public class MyAfterAdvice implements AfterReturningAdvice {@Overridepublic void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable {System.out.println("后置后置");}
}

3、配置spring配置文件

  • aop命名空间xmlns:aop="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd

  • 配置通知类<bean>
    <bean class="com.xs.advice.MyBeforeAdvice" id="before"></bean> <bean class="com.xs.advice.MyAfterAdvice" id="after"></bean>

  • 配置切面(切点与切面)

    <aop:config><aop:pointcut id="mypoint" expression="execution(* demo.Demo.demo01())"/><aop:advisor advice-ref="before" pointcut-ref="mypoint"></aop:advisor><aop:advisor advice-ref="after" pointcut-ref="mypoint"></aop:advisor></aop:config>
  • 匹配所有参数方法 (..)

配置异常通知

拦截service方法 (要抛出异常)

AspectJ 方式步骤

  • 任意类下任意方法
  • xml配置该类<bean>和切点bean
  • <aop:aspect>ref指向该bean
  • (spring知道异常通知所在类后还要知道其方法名)配置切点的同时<aop:after-throwing>配置其方法名,pointcut-ref指向切点,配置到切点上
  • 如果要知道异常信息,需要在写方法时给予形参,并利用throwing告知形参名
    <bean id="mythrow" class="com.xs.mythrow.MyThrowAdvice"></bean><bean id="demo" class="demo.Demo"></bean><aop:config><aop:aspect ref="mythrow"><aop:pointcut id="mypoint" expression="execution(* demo.Demo.demo01())"/><aop:after-throwing method="myexception" pointcut-ref="mypoint" throwing="e"></aop:after-throwing></aop:aspect></aop:config>

Schema-based 方式

  • 任意类名 afterThrowing方法名 且参数只能为1或4个(具体官方文档搜ThrowsAdvice)
  • 注意afterThrowing所抛出的异常名与切点抛出异常类型相同
  • 配置xml
    <bean id="demo" class="demo.Demo"></bean><bean id="mythrow" class="com.xs.mythrow.MyThrow"></bean><aop:config><aop:pointcut id="mypoint" expression="execution(* demo.Demo.demo01())"/><aop:advisor advice-ref="mythrow" pointcut-ref="mypoint"></aop:advisor></aop:config>
public class MyThrow implements ThrowsAdvice {public void afterThrowing(Exception ex) throws Throwable{System.out.println("异常异常");}
}

环绕配置

注意别导错包
注意.proceed();方法

public class MyAround implements MethodInterceptor {@Overridepublic Object invoke(MethodInvocation methodInvocation) throws Throwable {System.out.println("前置");Object proceed = methodInvocation.proceed();System.out.println("后置");return proceed;}
}

xml配置简单

    <bean id="myaround" class="com.xs.around.MyAround"></bean><bean id="demo" class="demo.Demo"></bean><aop:config><aop:pointcut id="mypoint" expression="execution(* demo.Demo.demo01())"/><aop:advisor advice-ref="myaround" pointcut-ref="mypoint"></aop:advisor></aop:config>

使用 AspectJ 方式实现

注意参数的配置,切点一旦配置了参数,其所有通知都要有形参

    <aop:config><aop:aspect ref="myadvice"><aop:pointcut expression="execution(* demo.Demo.demo01(String,String)) and args(msg,msg2) " id="mypoint"/><aop:before method="mybefore1" pointcut-ref="mypoint" arg-names="msg,msg2" ></aop:before><aop:after method="myafter" pointcut-ref="mypoint" ></aop:after>
<!--            <aop:after method="myafter" pointcut-ref="mypoint" arg-names="msg,msg2" ></aop:after>--></aop:aspect></aop:config><bean id="demo" class="demo.Demo"></bean><bean id="myadvice" class="com.xs.advice.MyAdvice"></bean>

本质就是把切点的参数拿过来给通知,让通知可以对其进行相关操作。

    public void mybefore1(String msg,String msg2){System.out.println("1:"+msg);System.out.println("2"+msg2);}public void myafter(String msg,String msg2){System.out.println("after");}

代理模式

JDK动态代理

public class Test {public static void main(String[] args) {MyProxy proxy = new MyProxy();//类加载器、实现哪个接口、具体是调用哪个对象的invoke方法//返回接口对象(实际是创建了一个实现该接口的proxy对象,该对象就是返回的接口对象)//接口对象调用方法时,把该方法传入invoke的Method形参中,并调用该invoke方法,该方法中利用反射(invoke(r,args))调用Real对象相关方法Impl impl = (Impl) Proxy.newProxyInstance(Test.class.getClassLoader(), new Class[]{Impl.class}, proxy);impl.sing();}
}
public class MyProxy implements InvocationHandler {private Real r = new Real();@Override//proxy 创建的代理对象 Method 方法(反射的方法) args 参数public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("前置");Object result = method.invoke(r, args);System.out.println("后置");return result;}
}

cglib动态代理

记得要导包

  • 基于字节码,生成真实对象的子类,运行效率高
        System.out.println("前置");//生成的子类对象调用需要代理的方法
//        Object result = method.invoke(o, objects);//报错?!!!!!! 待解决//生成的子类对象调用 需要代理的方法的Super方法即上一行的methodObject result = methodProxy.invokeSuper(o, objects);System.out.println("后置");return result;
        //传达 哪个类哪个对象 就对应生成了其子类Enhancer enhancer = new Enhancer();enhancer.setSuperclass(Real.class);enhancer.setCallback(new Proxy());Real r = (Real) enhancer.create();r.sing();

使用注解

组件扫描

<context:component-scan base-package="com.xs.advice"></context:component-scan>
  • @Component 组件id 默认为类名小写
  • @Component @Aspect 配置通知
  • 由于注解基于cglib,我们需要cglib动态代理
    <aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>

自动注入

  • default: 默认值,根据全局 default-autowire=””值.默认全局和局部都没有配置情况下,相当于 no
  • no:不自动注入
  • byName: 通过名称自动注入.在 Spring 容器中找类的 id
  • byType: 根据类型注入.spring 容器中不可以出现两个相同类型的bean
  • constructor: 根据构造方法注入 提供对应参数的构造方法(构造方法参数中包含注入对应那个) 底层使用byName, 构造方法参数名和其他bean的 id相同.
  • 全局使用default-autowire

加载properties文件

多个文件用逗号隔开

    <context:property-placeholder location="classpath:db.properties"></context:property-placeholder>

自动注入会影响sqlSessionFactory的注入,需要改成如下形式

<property name="sqlSessionFactoryBeanName" value="factory"></property>

使用@Value(${}) 注解 为属性赋值

记得添加扫描包的标签scan

Scope属性

  • bean 属性
  • 控制对象有效范围
  • singleton 默认值,单例
  • prototype 多例,每次获取重新实例化
  • request 每次请求重新实例化
  • session 每个会话对象内,对象是单例的.
  • application 在 application 对象内是单例
  • global session spring推出的一个对象,依赖于spring-webmvc-portlet ,类似于 session

声明式事务

  • 事务控制代码已经由 spring 写好.程序员只需要声明出哪些方 法需要进行事务控制和如何进行事务控制
  • 事务管理器基于通知(advice)的
    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"></bean><tx:advice id="txAdvice" transaction-manager="txManager"><tx:attributes><tx:method name="insert"/></tx:attributes></tx:advice>

和配置切面一样

  1. name=”” 哪些方法需要有事务控制
    1.1 支持*通配符
  2. readonly=”boolean” 是否是只读事务.
    2.1 如果为 true,告诉数据库此事务为只读事务.数据化优化,会对性能有一定提升,所以只要是查询的方法,建议使用此数据. 2.2 如果为 false(认值),事务需要提交的事务.建议新增,删除,修改.
  3. propagation 控制事务传播行为.
    3.1 当一个具有事务控制的方法被另一个有事务控制的方法调用后,需要如何管理事务(新建事务?在事务中执行?把事务挂起?报异常?)
    3.2 REQUIRED (默认值): 如果当前有事务,就在事务中执行,如果当前没有事务,新建一个事务.
    3.3 SUPPORTS:如果当前有事务就在事务中执行,如果当前没有事务,就在非事务状态下执行.
    3.4 MANDATORY:必须在事务内部执行,如果当前有事务,就在事务中执行,如果没有事务,报错.
    3.5 REQUIRES_NEW:必须在事务中执行,如果当前没有事务,新建事务,如果当前有事务,把当前事务挂起.
    3.6 NOT_SUPPORTED:必须在非事务下执行,如果当前没有事务,正常执行,如果当前有事务,把当前事务挂起.
    3.7 NEVER:必须在非事务状态下执行,如果当前没有事务,正常执行, 如果当前有事务,报错.
    3.8 NESTED:必须在事务状态下执行.如果没有事务,新建事务,如果当前有事务,创建一个嵌套事务.
  4. isolation=”” 事务隔离级别
    4.1 在多线程或并发访问下如何保证访问到的数据具有完整性的.
    4.2 脏读:
    4.2.1 一个事务(A)读取到另一个事务(B)中未提交的数据,另一个事务中数据可能进行了改变,此时 A事务读取的数据可能和数据库中数据是不一致的,此时认为数据是脏数据,读取脏数据过程叫做脏读.
    4.3 不可重复读:
    4.3.1 主要针对的是某行数据.(或行中某列)
    4.3.2 主要针对的操作是修改操作.
    4.3.3 两次读取在同一个事务内
    4.3.4 当事务 A 第一次读取事务后,事务 B 对事务 A 读取的淑君进行修改,事务 A 中再次读取的数据和之前读取的数据不一致,过程不可重复读.
    4.4 幻读:
    4.4.1 主要针对的操作是新增或删除
    4.4.2 两次事务的结果.
    4.4.3 事务 A 按照特定条件查询出结果,事务 B 新增了一条符合条件的数据.事务 A 中查询的数据和数据库中的数据不一致的,事务 A 好像出现了幻觉,这种情况称为幻读.
    4.5 DEFAULT: 默认值,由底层数据库自动判断应该使用什么隔离界别
    4.6 READ_UNCOMMITTED: 可以读取未提交数据,可能出现脏读,不重复读,幻读.
    4.6.1 效率最高.
    4.7 READ_COMMITTED:只能读取其他事务已提交数据.可以防止脏读,可能出现不可重复读和幻读.
    4.8 REPEATABLE_READ: 读取的数据被添加锁,防止其他事务修改此数据,可以防止不可重复读.脏读,可能出现幻读.
    4.9 SERIALIZABLE: 排队操作,对整个表添加锁.一个事务在操作数据时,另一个事务等待事务操作完成后才能操作这个表.
    4.9.1 最安全的
    4.9.2 效率最低的.
  5. rollback-for=”异常类型全限定路径”
    5.1 当出现什么异常时需要进行回滚
    5.2 建议:给定该属性值.
    5.2.1 手动抛异常一定要给该属性值
  6. no-rollback-for=”” 6.1 当出现什么异常时不滚回事务

SSM之Spring学习记录相关推荐

  1. SSM框架入门学习记录

    SSM框架入门学习记录 //项目结构 在这里插入图片描述 在这里插入图片描述 包名多种多样,命名习惯问题. 流程:Controller(接受请求)-->Service(biz)(bl)(写业务函 ...

  2. 我的Spring学习记录(二)

    本篇就简单的说一下Bean的装配和AOP 本篇的项目是在上一篇我的Spring学习记录(一) 中项目的基础上进行开发的 1. 使用setter方法和构造方法装配Bean 1.1 前期准备 使用sett ...

  3. Spring学习记录(九)---通过工厂方法配置bean

    1. 使用静态工厂方法创建Bean,用到一个工厂类 例子:一个Car类,有brand和price属性. 1 package com.guigu.spring.factory; 2 3 public c ...

  4. Spring 学习记录 冷兵器时代的故事

    这篇文章的内容和 Spring 没什么关系,但还是分类到 Spring 学习了. 首先,我们来将一个故事. 很久很久以前,冷兵器时代,人们用弓和箭打仗. 版本1 public class BowAnd ...

  5. Spring学习记录

    Spring相关 目录 文章目录 Spring相关 目录 前言 工厂设计模式 静态工厂模式 通用工厂模式 ApplicationContext ClassPathXmlApplicationConte ...

  6. spring学习记录(一)

    一.spring概述 spring是什么 Spring是分层的 Java SE/EE应用 full-stack 轻量级开源框架,以 IoC(Inverse Of Control: 反转控制)和 AOP ...

  7. Spring学习记录-Java 11运行eureka-server报javax.xml.bind.JAXBContext not present错

    在pom.xml加入依赖就行 <dependency><groupId>org.glassfish.jaxb</groupId><artifactId> ...

  8. SSM之Spring文件配置/Spring怎么在pom文件中进行依赖注入/不同的依赖注入类型有哪些以及怎么写

    写在前面: 接着记录自己的Spring学习之旅,若看不懂则建议先看上一篇博客SSM框架之Spring介绍开发流程/IDEA如何建立Spring项目,详细代码可在我的Gitee仓库ssm-learnin ...

  9. Java开发指导记录表_java 日常学习记录

    前言:记录自己初学java 遇到的问题. 环境(win10  开始安装的IDEA,net 开发者  )学习网址:http://how2j.cn/stage/14.html (不是打广告) 特别是对初学 ...

最新文章

  1. 使用JavaMail发送邮件
  2. php组件化开发composer,PHP组件化开发 - JimmyJaw的个人空间 - OSCHINA - 中文开源技术交流社区...
  3. python 词云手把手_手把手教你用python制作属于你的第一个词云
  4. dubbo学习之服务消费者
  5. 在MFC中添加用户自定义消息
  6. 【ubuntu】vim语法高亮设置无效
  7. Csminify:C#源代码的合并/缩小器
  8. axis在matlab中是什么意思_珠宝首饰上的钢印是什么意思呢?你都知道吗
  9. 解析HttpURLConnection与代理服务器
  10. Python面向对象(初识)
  11. npoi excel导入html数据库,C#_.NetFramework_Web项目_NPOI_EXCEL数据导入
  12. 笔记本 续航测试软件,续航能力测试
  13. 六大IT运维服务管理问题总结
  14. Discuz安装短信宝短信插件教程
  15. 89c51控制小车运行c语言,STC89C52单片机蓝牙遥控小车代码
  16. PyCharm安装教程最新版(社区版)
  17. Datawhale组队学习-NLP新闻文本分类-TASK05
  18. 微信开放平台与公众平台授权区别
  19. android音乐播放器上一首,安卓源码(音乐播放器,有播放和下一首,和进度条等功能)...
  20. python将CSV文件转为excel

热门文章

  1. 混沌图像---蔡氏电路的漩涡
  2. Android实现第三方登录并获取到头像、名字
  3. P1719 最大加权矩形
  4. matlab 海面反射,海面波浪模拟 MATLAB
  5. 从国足1:5输泰国看项目管理之项目失败责任该有谁负
  6. 14款国内外精品PPT模板网站对比介绍
  7. 杰里之AI 唤醒SIRI功能篇
  8. locust之安装(3)
  9. 高斯消元(Gauss-Jordan Elimination)
  10. 使用python下载图片(新手代码)