【总结】spring基础
一.spring
1.spring体系结构
(1)核心容器(core container):由spring-core,spring-beans,spring-context和spring-expression(SpEL,Spring表达式语言,Spring Expression Language)等模块组成
(2)数据访问(data access):jdbc,orm(jpa,heribate),transactions
(3)web:web,web-mvc,web-socket
(4)其它:aop,AspectJ,测试模块(JUnit)
2.ApplicationContext三个常见实现类
(1).classPathXmlApplicationContext:加载类路径下的配置文件(要求配置文件必须在类路径下,不在的话就加载不了)
(2).FileSystemXmlApplicationContext:加载磁盘任意路径下的配置文件(必须有访问权限)
(3).AnnotationConfigApplicationContext:读取注解创建容器
3.BeanFactory和ApplicationContext区别?
ApplicationContext继承BeanFactory接口,是一种更高级的容器,提供了更多功能(Aop,国际化,消息发送)
区别:BeanFactory在启动的时候不会实例化Bean,从容器拿bean的时候才会实例化。ApplicationContext在启动的时候就把所有Bean实例化
4.配置详解
<?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: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 https://www.springframework.org/schema/context/spring-context.xsd">
<!--mybatis -->
<context:property-placeholder location="classpath:jdbc.properties" system-properties-mode="NEVER"/>
<bean name="dataSouce" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="url" value="${url}"/>
<property name="username" value="${user}"/>
<property name="password" value="${password}"/>
<property name="driverClassName" value="${driver}"/>
</bean>
<bean class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSouce"/>
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.kkb.dao"/>
</bean>
<!--mybatis END -->
<!--注解扫描 -->
<context:component-scan base-package="com.kkb.service"/>
</beans>
(1)bean元素:使用该元素描述需要spring容器管理对象
(2)name属性:给被管理的对象起个名字,获得对象时getBean("name值")
(3)class属性:被管理对象的完整类名
(4)id属性:与name属性一模一样,名称不可重复,不能使用特殊字符
id与name的区别?
①id是唯一的,配置文件中不允许出现两个id相同的。中允许出现两个name相同的,在用getBean()返回实例时,后面一个Bean被返回
②如果没有配置id和name,则用类的全名作为name
(5)scope:singleton,prototype,request,session
绝大多数情况下,使用单例singleton(默认值),但是在与struts整合时候,务必要用prototype多例,因为struts2在每次请求都会创建一个新的Action,若为单例,在多请求情况下,每个请求找找spring拿的都是同一个action
(6)初始化和销毁:init-method,destory-method。spring会在对象创建之后立刻调用 init-method 对应注解为@PreDestory,spring容器在关闭并销毁所有容器中的对象之前调用destory-method对应注解为@PostConstruct
5.spring三种对象的创建方式
(1)空参构造
<!-- 使用无参构造函数创建对象 -->
<bean id="bean3" class="cn.itcast.beans.Bean3"></bean>
(2)静态工厂创建
<!-- 静态工厂创建(调用静态方法创建) -->
<bean name="user" class="cn.itcats.UserFactory" factory-method="createUser"></bean>
public class Bean1_factory {
public static Bean1 getBean(){
return new Bean1();
}
}
public class Bean1 {
public void add(){
System.out.println("bean1 ........");
}
}
(3)实例工厂
需要配置两个bean,因为无法通过类名调用非静态方法
<!-- 使用实例工厂创建对象 -->
<bean id="bean2_fcty" class="cn.itcast.beans.Bean2_factory">
<bean id="bean2" factory-bean="bean2_fcty" factory-method="getBean"></bean>
public class Bean2_factory {
public Bean2 getBean(){
return new Bean2();
}
}
public class Bean2 {
public void add(){
System.out.println("bean2 ........");
}
}
6.spring注入方式
(1)构造方法注入
使用对象的话,应改用ref属性
<bean id="user" class="bean.User">
<constructor-arg index="0" name="username" value="zhangsan"></constructor-arg>
<constructor-arg index="1" name="password" value="1234"></constructor-arg>
</bean>
(2)set注入
与构造器注入相比,只是少了index属性
<bean id="userService" class="com.lyu.spring.service.impl.UserService">
<property name="userDao" ref="userDaoMyBatis"></property>
</bean>
(3)注解注入
①引用类型注入:
@Autowired:spring注解,默认是以byType的方式去匹配,如果没有找到,就通过byName的方式去查找
@Resource:java的注解,默认以byName的方式去匹配,如果没有找到就会以byType的方式查找
@Qualifier:(spring注解)指定某个具体名称的bean(配合autowired和resource使用)
②值类型注入
@Value("kaka")
@Resource
@Qualifier("userDaoMyBatis")
private IUserDao userDao;
public UserService(){
@Autowired
@Qualifier("userDaoJdbc")
private IUserDao userDao;
7.复杂类型注入
<!-- 注入复杂类型属性 -->
<bean id="user" class="com.siwuxie095.property.User">
<!-- 数组 -->
<property name="arr">
<list>
<value>小孙</value>
<value>小李</value>
</list>
</property>
<!-- List 集合 -->
<property name="list">
<list>
<value>张三</value>
<value>李四</value>
<value>王五</value>
</list>
</property>
<!-- Map 集合 -->
<property name="map">
<map>
<entry key="a" value="老大"></entry>
<entry key="b" value="老二"></entry>
</map>
</property>
<!-- Properties 类型 -->
<property name="properties">
<props>
<prop key="username">root</prop>
<prop key="password">8888</prop>
</props>
</property>
</bean>
8.web.xml中spring的配置
<!--spring随项目的创建而创建,随项目的关闭而关闭,避免创建多个ApplicationContext-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--指定加载spring配置文件的位置-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
9.spring整合junit
@RunWith(SpringJUnit4ClassRunner.class) //RunWith用于指定junit运行环境,是junit提供给其他框架测试环境接口扩展
@ContextConfiguration("classpath:applicationContext.xml") //配置xml文件
public class Demo {
@Autowired
private User user;
@Test
public void fun01() {
System.out.println(user);
}
}
10.spring的aop中名词解释
(1)JoinPoint(连接点):目标对象中,所有可以增强的方法,就是spring允许你是通知(Advice)的地方,那可就真多了,基本每个方法的前、后(两者都有也行),或抛出异常是时都可以是连接点,spring只支持方法连接点。
(2)Pointcut(切入点):目标对象中,已经被增强的方法。调用这几个方法之前、之后或者抛出异常时干点什么,那么就用切入点来定义这几个方法。
(3)Advice(通知/增强) :增强方法的代码、想要的功能
(4)Target(目标对象):被代理对象,被通知的对象,被增强的类对象
(5)Weaving(织入):将通知应用到连接点形成切入点的过程
(6)Proxy(代理):将通知织入到目标对象之后形成的代理对象
(7)aspect(切面):切入点+通知
11.aop实现(基于注解)
@Before 前置通知(Before advice) :在某连接点(JoinPoint)——核心代码(类或者方法)之前执行的通知,但这个通知不能阻止连接点前的执行。为啥不能阻止线程进入核心代码呢?因为@Before注解的方法入参不能传ProceedingJoinPoint,而只能传入JoinPoint。要知道从aop走到核心代码就是通过调用ProceedingJionPoint的proceed()方法。而JoinPoint没有这个方法。
这里牵扯区别这两个类:Proceedingjoinpoint 继承了 JoinPoint 。是在JoinPoint的基础上暴露出 proceed 这个方法。proceed很重要,这个是aop代理链执行的方法。暴露出这个方法,就能支持 aop:around 这种切面(而其他的几种切面只需要用到JoinPoint,这跟切面类型有关), 能决定是否走代理链还是走自己拦截的其他逻辑。建议看一下 JdkDynamicAopProxy的invoke方法,了解一下代理链的执行原理。这样你就能明白 proceed方法的重要性。
@After 后通知(After advice) :当某连接点退出的时候执行的通知(不论是正常返回还是异常退出)。
@AfterReturning 返回后通知(After return advice) :在某连接点正常完成后执行的通知,不包括抛出异常的情况。
@Around 环绕通知(Around advice) :包围一个连接点的通知,类似Web中Servlet规范中的Filter的doFilter方法。可以在方法的调用前后完成自定义的行为,也可以选择不执行。这时aop的最重要的,最常用的注解。用这个注解的方法入参传的是ProceedingJionPoint pjp,可以决定当前线程能否进入核心方法中——通过调用pjp.proceed();
@AfterThrowing 抛出异常后通知(After throwing advice) : 在方法抛出异常退出时执行的通知。
@Aspect //@Aspect注解代表该类是个通知类,书写切点表达式@Pointcut("execution(返回值 全类名.方法名(参数))")
public class LogAspect {
//抽取公共的切入点表达式
//1、本类引用
//2、其他的切面引用
@Pointcut("execution(* com.gz.MathCalculator.*(..))")
public void pointCut(){};
@Before("pointCut()")
public void logStart(JoinPoint joinPoint){
Object[] args = joinPoint.getArgs();
System.out.println(""+joinPoint.getSignature().getName()+"运行。。。@Before:参数列表是:{"+Arrays.asList(args)+"}");
}
@After("com.gz.LogAspect.pointCut()")
public void logEnd(JoinPoint joinPoint){
System.out.println(""+joinPoint.getSignature().getName()+"结束。。。@After");
}
@AfterReturning(value="pointCut()",returning="result")
public void logReturn(JoinPoint joinPoint,Object result){
System.out.println(""+joinPoint.getSignature().getName()+"正常返回。。。@AfterReturning:运行结果:{"+result+"}");
}
@AfterThrowing(value="pointCut()",throwing="exception")
public void logException(JoinPoint joinPoint,Exception exception){
System.out.println(""+joinPoint.getSignature().getName()+"异常。。。异常信息:{"+exception+"}");
}
}
(1)@Before 前置通知(Before advice) :在某连接点(JoinPoint)之前执行的通知
(2)@After 后通知(After advice) :当某连接点退出的时候执行的通知(不论是正常返回还是异常退出)
(3)@AfterReturning 返回后通知(After return advice) :在某连接点正常完成后执行的通知,不包括抛出异常的情况
(4)@AfterThrowing 抛出异常后通知(After throwing advice) : 在方法抛出异常退出时执行的通知
(5)@Around 环绕通知(Around advice):包围一个连接点的通知,类似Web中Servlet规范中的Filter的doFilter方法。可以在方法的调用前后完成自定义的行为,也可以选择不执行
12.spring中事务
spring中事务可以分为编程式事务控制和声明式事务控制
编程式事务:自己手动控制事务,就叫做编程式事务控制。 【细粒度的事务控制: 可以对指定的方法、指定的方法的某几行添加事务控制】比较灵活,但开发起来比较繁琐: 每次都要开启、提交、回滚
声明式事务:Spring提供了对事务的管理, 这个就叫声明式事务管理【粗粒度的事务控制: 只能给整个方法应用事务,不可以对方法的某几行应用事务】 (因为aop拦截的是方法)
13.事务传播行为
事务传播行为(propagation behavior)指的就是当一个事务方法被另一个事务方法调用时,这个事务方法应该如何进行。
例如:methodA事务方法调用methodB事务方法时,methodB是继续在调用者methodA的事务中运行呢,还是为自己开启一个新事务运行,这就是由methodB的事务传播行为决定的。
(1)propagation_required:如果存在一个事务,则支持当前事务。如果没有事务则开启一个新的事务。
(2)propagation_supports:如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行
@Transactional(propagation = Propagation.REQUIRED)
public void methodA() {
methodB();
// do something
}
// 事务属性为SUPPORTS
@Transactional(propagation = Propagation.SUPPORTS)
public void methodB() {
// do something
}
单纯的调用methodB时,methodB方法是非事务的执行的。当调用methdA时,methodB则加入了methodA的事务中,事务地执行
(3)propagation_mandatory:如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常
(4)propagation_requires_new:它会开启一个新的事务。如果一个事务已经存在,则先将这个存在的事务挂起(需要使用 JtaTransactionManager作为事务管理器)
(5)propagation_not_supported:总是非事务地执行,并挂起任何存在的事务。使用PROPAGATION_NOT_SUPPORTED(也需要使用JtaTransactionManager作为事务管理器)
(6)propagation_never:总是非事务地执行,如果存在一个活动事务,则抛出异常。
(7)propagation_nested: 如果一个活动的事务存在,则运行在一个嵌套的事务中。 如果没有活动事务, 则按propagation_required属性执行(嵌套事务一个非常重要的概念就是内层事务依赖于外层事务。外层事务失败时,会回滚内层事务所做的动作。而内层事务操作失败并不会引起外层事务的回滚)
14.propagation_nested 与propagation_requires_new的区别?
它们非常类似,都像一个嵌套事务,如果不存在一个活动的事务,都会开启一个新的事务。
(1)使用 PROPAGATION_REQUIRES_NEW时,内层事务与外层事务就像两个独立的事务一样,一旦内层事务进行了提交后,外层事务不能对其进行回滚。两个事务互不影响。两个事务不是一个真正的嵌套事务。同时它需要JTA事务管理器的支持。
(2)使用PROPAGATION_NESTED时,外层事务的回滚可以引起内层事务的回滚。而内层事务的异常并不会导致外层事务的回滚,它是一个真正的嵌套事务。DataSourceTransactionManager支持
15.aop管理事务(注解)
(1)开启注解
<tx:annotation-driven/>
(2)方法上增加@Transactional注解方法就可以被事务管理起来
@Transactional注解的属性:
readOnly : 是否仅仅只读。默认读写都可以
timeout : 事务超时时间,默认没有超时时间
isolation: 事务的隔离级别 默认:TransactionDefinition.ISOLATION_DEFAULT(大部分数据库的默认隔离级别是可重复读)
propagation :事务的传播属性 默认:TransactionDefinition.PROPAGATION_REQUIRED
【总结】spring基础的更多相关文章
- Spring基础知识
Spring基础知识 利用spring完成松耦合 接口 public interface IOutputGenerator { public void generateOutput(); } 实现类 ...
- spring基础整理
spring基础教程:https://www.tutorialspoint.com/spring/spring_overview.htm 注入实例 <bean id="" c ...
- Spring 基础知识
Spring架构简单描述 原文:https://www.shiyanlou.com/courses/document/212 Spring 概述 1. Spring 是什么 Spring是一个开源的轻 ...
- Spring基础配置
从毕业到现在我一直从事Android开发,但是对JavaEE一直念念不忘,毕业校招的时候,一个礼拜拿了三个offer,岗位分别是Android.JavaEE和JavaSE,后来觉得Android比较简 ...
- Spring基础系列--AOP织入逻辑跟踪
原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/9619910.html 其实在之前的源码解读里面,关于织入的部分并没有说清楚,那些前置.后 ...
- 第65节:Java后端的学习之Spring基础
Java后端的学习之Spring基础 如果要学习spring,那么什么是框架,spring又是什么呢?学习spring中的ioc和bean,以及aop,IOC,Bean,AOP,(配置,注解,api) ...
- Spring基础系列-AOP源码分析
原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/9560803.html 一.概述 Spring的两大特性:IOC和AOP. AOP是面向切 ...
- Spring基础系列-Spring事务不生效的问题与循环依赖问题
原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/9476550.html 一.提出问题 不知道你是否遇到过这样的情况,在ssm框架中开发we ...
- Spring Boot实战(1) Spring基础
1. Spring基础配置 Spring框架本身有四大原则: 1) 使用POJO进行轻量级和最小侵入式开发 2) 通过依赖注入和基于接口编程实现松耦合 3) 通过AOP和默认习惯进行声明式编程 4) ...
- spring基础学习01
spring基础 Spring是一个开放源代码的设计层面框架,他解决的是业务逻辑层和其他各层的松耦合问题,因此它将面向接口的编程思想贯穿整个系统应用 IOC控制反转 把创建对象和维护对象之间的关系权利 ...
随机推荐
- Mysql的ONLY_FULL_GROUP_BY
今天在测试环境遇到一个问题,本地测试是没有问题,在测试环境sql报错了: nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLSyntax ...
- android开发之意图
intent 全局变量传值(程序关闭时存储值消失) intent普通传值 intent传值 intent不能序列化传值 intent回传
- (转载)什么是B+树?
本文转载自网络. 如有侵权,请联系处理!
- PyCharm-缩进 格式化代码
格式化代码 Ctrl + Alt + l 缩进代码 Tab 向右缩进4格 Shift + Tab 向左缩进4格
- Centos-切换用户身份-su
su 切换用户身份 相关选项 - 加载相应用户下环境变量 -c 使用某个身份执行一个指令 -m 改变用户身份不改变环境变量 切换为超级用户 su - 普通用户切换为超级用户需要输入密码,超级用户 ...
- Python-py2和py3读写文本区别
python2和python3的区别? python 2 str 对应 python3 bytes python 2 uincode 对应 ...
- Intel HEX格式
来来 !! come baby ! 只强调一点这篇文章有checksum的算法,是我最喜欢地!! 参考:https://blog.csdn.net/extlife/article/details/ ...
- 从字节码层次看i++和++i
关于的Java的i++和++i的区别,初学者可能会混淆,这时候有经验的同学或同事就会告诉你,++在后,就会立马加值, ++在后则会等会儿再加,所以如果i == 0 ,那么i++ == 0,++i == ...
- 每日一题 LeetCode 42.接雨水 【双指针】
题目链接 https://leetcode-cn.com/problems/trapping-rain-water/ 题目说明 题解 主要方法:双指针 + 正反遍历 解释说明: 正向遍历:先确定池子左 ...
- dirsearch下载与简单实用
下载 下载地址 我的电脑是Windows,而且我也有python3.6的环境,所以我是直接clone到本地就能使用了. 命令的提示在上面的下载地址里就有,这里给个最简单的命令(脚本小子专属,我 ...