关于spring的学习笔记
1.1简介
- spring:春天------------》给软件行业带来春天- 2002,首次推出了spring框架的:interface21框架- 2004年3月24号,诞生- Rod Johnson,baiSpring Framework创始人,著名作者。‘- spring的理念:是现有的技术更加容易使用,本身是一个大杂烩。整合现有的技术框架。
官网:https://spring.io/projects/spring-framework
官方下载地址:https://repo.spring.io/release/org/springframework/spring/
github地址:https://github.com/spring-projects/spring-framework
1.2优点
免费的开源框架!
轻量级的非入侵,轻量型的框架!
控制反转(ioc),面向切面(aop)
支持事务的处理
1.3组成
1.4扩展
spring的官网有这个介绍:现代化的java开发,其实都是基于spring
2.ioc创建对象的方法
- 使用无参构造创建对象
package com.dbh.spring01.entity;public class User {private String name;public User() {System.out.println("User 的无参构造");}public String getName() {return name;}public void setName(String name) {this.name = name;}public void show() {System.out.println("name="+this.name);}@Overridepublic String toString() {return "User [name=" + name + "]";}}
<?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/beanshttps://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="user" class="com.dbh.spring01.entity.User"><property name="name" value="zs"></property></bean></beans>
- 使用有参构造创建对象
package com.dbh.spring01.entity;public class User {private String name;public User(String name) {System.out.println("User 的无参构造");}public String getName() {return name;}public void setName(String name) {this.name = name;}public void show() {System.out.println("name="+this.name);}@Overridepublic String toString() {return "User [name=" + name + "]";}}
<?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/beanshttps://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="user" class="com.dbh.spring01.entity.User"><!-- 下标赋值--><!-- <constructor-arg index="0" value="dbh"/> --><!-- 参数类型赋值 不建议使用,如果参数中有相同的--><!-- <constructor-arg type="java.lang.String" value="hello"/> --><!--直接通过参数名设置 --><constructor-arg name="name" value="hello"/></bean></beans>
总结:在配置文件加载的时候,容器中管理的对象就已经创建了!
3.spring配置
别名
<!-- id bean的唯一标识 class bean的位置报名+类名 name:别名 可以创建多个,可以使用,;分割--><bean id="userT" class="com.dbh.spring01.entity.UserT" name="t;h"><constructor-arg name="name" value="dbh"></constructor-arg></bean><alias name="userT" alias="f"/>
import
一般用于团队开发,可以将多个配置文件,导入合并为一个
<import resource="bean3.xml"/> <import resource="beans2.xml"/> <import resource="beans.xml"/>
4.DI注入
构造器注入
<bean id="userT" class="com.dbh.spring01.entity.UserT" name="t;h"><constructor-arg name="name" value="dbh"></constructor-arg>
set方式注
入依赖注入:
依赖:bean对象的创建依赖于容器
注入:bean对象的所有属性,由容器来注入
测试实现
package com.dbh.spring01.entity;import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set;public class Studnet {private String name;private Address address;private String[] strings;private List<String> list;private Map<String, String> map;private Set<String> set;private Properties properties;private String wife;public String getName() {return name;}public void setName(String name) {this.name = name;}public Address getAddress() {return address;}public void setAddress(Address address) {this.address = address;}public String[] getStrings() {return strings;}public void setStrings(String[] strings) {this.strings = strings;}public List<String> getList() {return list;}public void setList(List<String> list) {this.list = list;}public Map<String, String> getMap() {return map;}public void setMap(Map<String, String> map) {this.map = map;}public Set<String> getSet() {return set;}public void setSet(Set<String> set) {this.set = set;}public Properties getProperties() {return properties;}public void setProperties(Properties properties) {this.properties = properties;}public String getWife() {return wife;}public void setWife(String wife) {this.wife = wife;}@Overridepublic String toString() {return "Studnet [name=" + name + ", address=" + address + ", strings=" + Arrays.toString(strings) + ", list="+ list + ", map=" + map + ", set=" + set + ", properties=" + properties + ", wife=" + wife + "]";}}package com.dbh.spring01.entity;public class Address {private String address;public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}@Overridepublic String toString() {return "Address [address=" + address + "]";}}
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/beanshttps://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="address" class="com.dbh.spring01.entity.Address" name="a"><property name="address" value="湖南长沙" /></bean><bean id="student" class="com.dbh.spring01.entity.Studnet" name="s"><!-- String --><property name="name" value="戴戴" /><!--对象 --><property name="address" ref="address" /><!--数组 --><property name="strings"><array><value>西游戏</value><value>红楼梦</value><value>三国演义</value><value>水浒传</value></array></property><!-- list --><property name="list"><list><value>吃饭</value><value>睡觉</value><value>java</value><value>喝水</value></list></property><!--map --><property name="map"><map><entry key="name" value="dbh" /><entry key="age" value="12" /><entry key="sex" value="男" /><entry key="address" value="湖南长沙" /></map></property><!-- set --><property name="set"><set><value>1</value><value>2</value><value>3</value><value>4</value><value>5</value></set></property><!-- null --><property name="wife"><null /></property><!--properties --><property name="properties"><props><prop key="yhk">45461156151</prop><prop key="sfz">1312312323</prop><prop key="yxid">1312333</prop></props></property></bean></beans>
测试
package spring01test;import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;import com.dbh.spring01.entity.Studnet;public class Test4 {@Testpublic void test() {ApplicationContext context = new ClassPathXmlApplicationContext("studentbeans.xml");Studnet student = (Studnet)context.getBean("student");System.out.println(student);}}
拓展注入
可以是用p命名空间和c命名空间注入
<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:c="http://www.springframework.org/schema/c"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsd"><!-- p命名的空间注入,可以直接注入属性的值 本质上时set注入--><bean id="puser" class="com.dbh.spring01.entity.PUser" p:name="dbh" p:age="18" p:address-ref="address"></bean><bean id="address" class="com.dbh.spring01.entity.Address" p:address="湖南长沙"></bean><!-- c命名的空间注入,其实时构造器注入--><bean id="puser1" class="com.dbh.spring01.entity.PUser" c:name="dbh" c:age="12" c:address-ref="address"></bean></beans>
注意点:p和c命名空间不能直接使用,需要导入xml约束
xmlns:p="http://www.springframework.org/schema/p" xmlns:c="http://www.springframework.org/schema/c"
5.bean的作用域
scope(作用域):默认时单例
1.单例:singleton:单例
<bean id="puser1" class="com.dbh.spring01.entity.PUser" c:name="dbh" c:age="12" c:address-ref="address" scope="singleton"></bean>
2.原型:每次从容器中get的时候多会产生一个新的对象
<bean id="accountService" class="com.something.DefaultAccountService" scope="prototype"/>
3.其余的request,session,application这些只能在web开发才能使用到。
6.bean的自动装配
- 自动装配是spring满足bean依赖的一种方式
- spring会去spring的上下文中自动寻找,并自动给bean装配属性
spring中有三种装配的方式
在xml中显示的配置、
在java中显示的配置
隐式的自动装配bean(重点)
BYNAME自动装配
<!-- byName:会自动在容器的上下文查找,和自己对象set方法后面的值对应的beanid--> <bean id="people" class="com.dbh.pro.entity.People" autowire="byName"></bean><bean id="dog" class="com.dbh.pro.entity.Dog"></bean> <bean id="cat" class="com.dbh.pro.entity.Cat"></bean>
BYTYPE自动装配
<!-- byType:会自动在容器上下文查找,和自己对象属性类型形同的bean!--> <bean id="people" class="com.dbh.pro.entity.People" autowire="byType"></bean><bean class="com.dbh.pro.entity.Dog"></bean> <bean class="com.dbh.pro.entity.Cat"></bean>
小结:
byName的时候,需要保证所有bean的id唯一,并且这个bean需要和自动注入的属性的set方法后面的值保持一致!
bytype的时候,需要保证所有的bean的class唯一。并且这个bean需要和自动注入的属性的类型一致!
使用注解实现自动装配
jdk1.5支持注解,spring2.5支持注解
要使用注解须知:
导入约束: context约束
配置注解的支持: context:annotation-config/
<?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/beanshttps://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttps://www.springframework.org/schema/context/spring-context.xsd"><context:annotation-config/></beans>
@Autowired
可以在属性上使用,也可以在set方法中使用。
使用Autowired,我们可以不用set方法了。前提是你这个自动配置的属性在自动装配的属性在ioc(spring)容器中存在,且符合名字
测试代码
@Autowired
@Qualifier("cat")
private Cat cat;@Autowired
@Qualifier("dog")
private Dog dog;public Cat getCat() {return cat;
}public void setCat(Cat cat) {this.cat = cat;
}public Dog getDog() {return dog;
}public void setDog(Dog dog) {this.dog = dog;
}
如果@Autowiired自动装配的环境比较复杂,无法通过一个注解完成时。可以通过@Qualifier配和使用。指定唯一的bean。
@Resource(name="cat111")
private Cat cat;@Resource(name="Dog")
private Dog dog;
@Resource和@autowired的区别:
- 都是用来自动装配的,都可以放到属性字段上
- @Resource的作用相当于@Autowired,只不过@Autowired按byType自动注入,而@Resource默认按 byName自动注入罢了。@Resource有两个属性是比较重要的,分是name和type,Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。所以如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策略。如果既不指定name也不指定type属性,这时将通过反射机制使用byName自动注入策略。
@Resource装配顺序
1. 如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常
2. 如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常
3. 如果指定了type,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常
4. 如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配;
7.注解开发
<?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/beanshttps://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttps://www.springframework.org/schema/context/spring-context.xsd"><!--指定那个包下的注解有用 --><context:component-scan base-package="com.dbh.pro"></context:component-scan><!--提供注解的支持 --><context:annotation-config/></beans>
在spring4后,必须要有aop的jar包。才能使用。使用注解
使用注解需要导入context约束,增加注解的支持!
@Component:组建,放在类上,说明这个类被spring管理了,就是bean!等价于
@value(“周杰伦”)等价于可以放在属性或者set方法上
@Component有好几个衍生注解,功能其实都一样
dao层:@Repository
service层:@Service
controller层:@Controller
这四个注解功能都是一样的,都代表将某个类注册到spring中,装配bean
作用域
@Scope("")单例子 原型 request session application
总结:
xml和注解:
1. xml更加万能,适用于任何场景!维护简单2. 注解不是自己的类使用不了,维护相对复杂
xml与注解的最佳实践:
xml用来管理bean
注解负责完成属性的注入
使用过程中只需要注意一个问题,想要注解生效就需要开启注解的支持
9.使用java的方式配置spring
完全不使用spring的xml配置,全权交给java来做
javaConfig是spring的一个子项目,在spring4之后变成了核心功能
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hsCjGdyi-1597214457395)(新建文本文档.assets/image-20200807230003431.png)]
实例
- 实体类
package com.dbh.sp05.entity;import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;@Component //这个注解的意思,就是说明这个类被spring接管了,注册到容器中
public class User {private String name;public String getName() {return name;}@Value("周杰伦") //属性注入值public void setName(String name) {this.name = name;}}
配置类
package com.dbh.sp05.config;import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.stereotype.Component;import com.dbh.sp05.entity.User;//这个也会被spring容器托管,注册到容器中,本来就是一个@Component //@Configuration代表这是一个配置类,就和我们之前看的beans.xml一样@Configuration @ComponentScan("com.dbh.sp05") @Import(Config2.class) //相当于导入 public class Config {/*注册一个bean,相当于我们写的一个bean标签,这个方法的名字就相当于bean标签的id属性,返回值就相当于bean标签的class* 属性*/@Bean public User getUser() {return new User();//就是要返回要注入到bean的对象}}
测试类
package spring04;import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext;import com.dbh.sp05.config.Config; import com.dbh.sp05.entity.User;public class Spring04Test {@Testpublic void test() {//如果完全使用了配置类方式去做,我们只能通过AnnotationConfig上下文来获取容器,通过配置类的class对象加载ApplicationContext context = new AnnotationConfigApplicationContext(Config.class);User user = context.getBean("getUser", User.class);System.out.println(user.getName());}}
10. 代理模式
代理模式的分类:
- 静态代理
- 动态代理
10.1静态代理
分析:
抽象角色:一般会使用接口或者抽象类
代理角色:代理真实角色后,一般会做一些附属操作
真实角色:被代理的角色
客户:访问代理对象的人
代理模式的好处:
- 可以是真实的角色的操作更加纯粹,不需要去管一些公共的业务
- 公共的就交个代理角色,实现了业务的分工
- 公共业务扩展的时候,更加便于管理
缺点:
- 一个真实的角色就对应一个代理角色,代码量会翻倍。开发效率会变低
具体实现代码:
需要租房子的人(真实角色)
package com.dbh.prox.Demo;//房东 public class Host implements Rent{@Overridepublic void rent() {// TODO Auto-generated method stubSystem.out.println("房东租房子");}}
房产中介(代理角色)
package com.dbh.prox.Demo;public class Proxy implements Rent{private Host host;public Proxy() {}public Proxy(Host host) {this .host=host;}//代理帮房东租房子@Overridepublic void rent() {// TODO Auto-generated method stubhost.rent();seeHost();fare();hetong();}//看房public void seeHost() {System.out.println("中介帮你看房");}//收中介费public void fare() {System.out.println("收中介费");}//签合同public void hetong() System.out.println("签租房相关合同");}}
接口(租房子的具体方法)
package com.dbh.prox.Demo;public interface Rent {//租房子方法public void rent();}
客户端访问代理
package com.dbh.prox.Demo;import org.junit.Test;//租房子的人 public class Client {@Testpublic void test() {//房东需要租房子Host host=new Host();//代理 中介帮房东租房子,加上一些代理的附属操作Proxy proxy=new Proxy(host);//不用直接去找房东租房子,直接找中介租房子即可proxy.rent();} }
10.2动态代理
- 动态代理和静态代理的角色一样
- 动态代理的类动态生成的,不是我们写好的
- 动态代理分为两类:基于接口,基于类
- 基于接口:JDK动态代理【这里使用】
- 基于类:cglib
- java字节码:javassist
需要了解的2个类:Proxy:生成代理的, InvocationHandler:调用处理程序,并返回结果的
具体的实例:
//生成代理的类,必须是按invocationHandler
public class ProxUtils implements InvocationHandler {// 被代理的接口
private Object trage;public void setTrages(Object trage) {this.trage = trage;
}public Object get() {return Proxy.newProxyInstance(ProxUtils.class.getClassLoader(), trage.getClass().getInterfaces(), this);}@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// TODO Auto-generated method stublog(method.getName());return method.invoke(trage, args);
}public void log(String name) {System.out.println("[日志信息]: 调用的方法"+name);
}}
//代理对象和真实对象实现的接口
public interface UserService {//增public void add();//修改public void edit();//删除public void delete();//查询public void query();}
//真实对象 需要代理的类
public class UserServerImpl implements UserService{@Overridepublic void add() {// TODO Auto-generated method stubSystem.out.println("add一个用户");}@Overridepublic void edit() {// TODO Auto-generated method stubSystem.out.println("edit一个用户");}@Overridepublic void delete() {// TODO Auto-generated method stubSystem.out.println("delete一个用户");}@Overridepublic void query() {// TODO Auto-generated method stubSystem.out.println("query一个用户");}}
//具体实例
public class DemoProxy {@Testpublic void test() {UserService service=new UserServerImpl();ProxUtils proxUtils=new ProxUtils();proxUtils.setTrages(service);UserService object = (UserService)proxUtils.get();object.add();}}
动态代理的好处:
可以是真实的角色的操作更加纯粹,不需要去管一些公共的业务
公共的就交个代理角色,实现了业务的分工
公共业务扩展的时候,更加便于管理
一个动态代理类代理的是一个接口,一般就是对应的一类业务
一个动态代理类可以代理多个类,只要是实现了同一个接口即可
11.AOP
11.1AOP是什么
意为:面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
11.2Aop在spring中的作用
- 横切关注点:跨越应用程序多个模块的方法或功能.既是,与我们业务逻辑无关,但是我们需要关注的部分,就是横切关注点.如日志,安全,缓存,事务等…
- 切面(ASPECT):横切关注点 被模块化 的特殊对象。即,它是一个类。
- 通知(Advice):切面必须要完成的工作。即,它是类中的一个方法。
- 目标(Target):被通知对象。
- 代理(Proxy):向目标对象应用通知之后创建的对象。
- 切入点(PointCut):切面通知 执行的 “地点”的定义。
- 连接点(JointPoint):与切入点匹配的执行点。
需要导入的jar
<dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.4</version></dependency>
- 方式一:使用原生态的api接口
<?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:aop="http://www.springframework.org/schema/aop"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttps://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttps://www.springframework.org/schema/aop/spring-aop.xsd"><!-- 注入bean --><bean id="userservice" class="com.dbh.aop.service.UserserviceImpl"></bean><bean id="afterLog" class="com.dbh.aop.log.AfterLog"></bean><bean id="beforLog" class="com.dbh.aop.log.BeforLog"></bean><!-- 配置aop 方式一 --><aop:config><!--切入点 expression表达式 --><!-- pointcut属性用来定义一个切入点,分成四个部分理解 [* ][*..][*Service][.*(..)] --><!-- A: 返回类型,*表示返回类型不限 --><!-- B: 包名,*..表示包名不限 --><!-- C: 类或接口名,*Service表示类或接口必须以Service结尾 --><!-- D: 方法名和参数,*(..)表示方法名不限,参数类型和个数不限 --><aop:pointcut id="pointcut" expression="execution(* *..*Service.*(..))" /><!-- 执行环绕 --><aop:advisor advice-ref="afterLog" pointcut-ref="pointcut" /><aop:advisor advice-ref="beforLog" pointcut-ref="pointcut" /></aop:config>
</beans>
//后置通知public class AfterLog implements AfterReturningAdvice{@Overridepublic void afterReturning(Object reObject, Method method, Object[] arg2, Object target) throws Throwable {// TODO Auto-generated method stubSystem.out.println(target.getClass().getName()+"的"+method.getName()+"方法,返回了"+reObject); }}
//前置通知
public class BeforLog implements MethodBeforeAdvice{//Method 要执行的目标的方法//objects 参数//target 目标对象@Overridepublic void before(Method method, Object[] objects, Object target) throws Throwable {// TODO Auto-generated method stubSystem.out.println(target.getClass().getName()+"的"+method.getName()+"方法");}//接口public interface UserService {public void add();public void edit();public void delete();public void select();
}//实现类public class UserserviceImpl implements UserService{@Overridepublic void add() {// TODO Auto-generated method stubSystem.out.println("增加一个用户");}@Overridepublic void edit() {// TODO Auto-generated method stubSystem.out.println("修改一个用户");}@Overridepublic void delete() {// TODO Auto-generated method stubSystem.out.println("删除一个用户");}@Overridepublic void select() {// TODO Auto-generated method stubSystem.out.println("查询一个用户");}//测试类public class test {public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");//动态代理的是接口(注意)UserService userService = context.getBean("userservice",UserService.class);userService.add();}}
- 方式二:自定义类
<!--配置方式二 :自定义 --><aop:config><aop:aspect ref="zdy"><!-- 切入点 --><aop:pointcut id="point" expression="execution(* *..*Impl.*(..))"/><!-- 通知 --><aop:around method="hz" pointcut-ref="point"></aop:around> <aop:after method="befor" pointcut-ref="point"/><aop:before method="after" pointcut-ref="point"/></aop:aspect></aop:config>
自定义类的
public class DiypointCut {//前置public void befor() {System.out.println("之前");}//后置public void after() {System.out.println("之后");}//环绕public Object hz(ProceedingJoinPoint proceedingJoinPoint){System.out.println("before around==========");Object result=null;try {result= proceedingJoinPoint.proceed();} catch (Throwable e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println("after around==========");return result;}
方式三:注解实现
<!--方式三 --><bean id="annotationPointcut" class="com.dbh.aop.diy.AnnotationPointcut"></bean><!--开启注解支持 jdk(proxy-target-class="false" 默认使用) cglib(proxy-target-class="true") --><aop:aspectj-autoproxy proxy-target-class="false"/>
注解实现自定义的通知
//使用注解方式实现aop
@Aspect //标注这个类是一个切面
public class AnnotationPointcut {@Before("execution(* *..*Service.*(..))")public void before() {System.out.println("===执行前====");}@After("execution(* *..*Service.*(..))")public void after() {System.out.println("===执行后===");}}
测试和上面的一样
12.声明式事务
12.1事务
- 把一组业务当成一个业务来做,要么都成功要么都失败
- 确保数据的一致性
事务的ACID的原则:
- 原子性
- 隔离性
- 持久性
- 一致性
12.2spring中的事务管理
- 声明式事务:Aop
- 编辑式事务:需要在代码中,进行事务的管理·
实例
<!--2) 事务管理器 begin/commit/rollback --><bean id="transactionManager"class="org.springframework.orm.hibernate5.HibernateTransactionManager"><property name="sessionFactory" ref="sessionFactory" /></bean><!--结合aop --><tx:advice id="txAdvice" transaction-manager="transactionManager"><!-- 给那些方法配置事务 --><!--配置事务的传播途经 propagation=REQUIRED 默认--><tx:attributes><tx:method name="sw*" propagation="REQUIRED" /></tx:attributes></tx:advice><!-- 配置事务的切入--><aop:config><aop:advisor advice-ref="txAdvice" pointcut="execution(* *..*Service.*(..))" /></aop:config>
使用事务的原因:
- 如果不配置的话可能会出现数据不一致的情况
- 不再spring配置声明式事务,就需要在代码中手动配置事务
- 事务十分重要,涉及到数据的一致性和完整性
关于spring的学习笔记相关推荐
- Spring MVC 学习笔记 对locale和theme的支持
Spring MVC 学习笔记 对locale和theme的支持 Locale Spring MVC缺省使用AcceptHeaderLocaleResolver来根据request header中的 ...
- Spring Cloud 学习笔记(四)-Spring Cloud Hystrix
Spring Cloud 学习笔记(四)-Spring Cloud Hystrix 由于前一阵子项目的原因,今天才继续弄上,今天想学习一下Hystrix组件 这个组件还挺抽象的,最开始我一直没太明白, ...
- Spring Boot学习笔记-实践建言
2019独角兽企业重金招聘Python工程师标准>>> 本文延续<Spring Boot学习笔记-快速示例>,从开发指南中摘出一些实践经验可供参考.这也是笔者看到的眼前一 ...
- Spring.NET学习笔记10——方法的注入(基础篇) Level 200
多数用户都会将容器中的大部分对象布署为singleton模式.当一个singleton对象需要和另一个singleton对象协作,或者一个非singleton对象需要和另一个非singleson对象协 ...
- Spring.NET学习笔记——前言
Spring.NET是一个应用程序框架,其目的是协助开发人员创建企业级的.NET应用程序.它提供了很多方面的功能,比如依赖注入.面向方面编程(AOP).数据访问抽象及ASP.NET扩展等等.Sprin ...
- Spring Boot学习笔记-进阶(3)
文章目录 Spring Boot学习笔记-进阶(3) 一.Spring Boot与缓存 二.Spring Boot与消息 三.Spring Boot与检索 四.Spring Boot与任务 异步任务 ...
- Spring Boot学习笔记-基础(2)
Spring Boot学习笔记-基础(2) Spring Boot 优点: – 快速创建独立运行的Spring项目以及与主流框架集成 – 使用嵌入式的Servlet容器,应用无需打成WAR包 – st ...
- Spring Boot学习笔记(1)
文章目录 Spring Boot学习笔记(1) Spring Boot 整合 JSP Spring Boot HTML Thymeleaf 常用语法 Spring Boot 数据校验 Spring B ...
- Spring MVC 学习笔记一 HelloWorld
Spring MVC 学习笔记一 HelloWorld Spring MVC 的使用可以按照以下步骤进行(使用Eclipse): 加入JAR包 在web.xml中配置DispatcherServlet ...
- Spring Cloud 学习笔记(2 / 3)
Spring Cloud 学习笔记(1 / 3) Spring Cloud 学习笔记(3 / 3) - - - 56_Hystrix之全局服务降级DefaultProperties 57_Hystri ...
最新文章
- DCASE 2013任务1(声学场景分类)参赛作品相关信息
- iOS开发UI篇-在UItableview中实现加载更多功能
- java文件读入原理_描述一下JVM加载class文件的原理机制
- 链家信息python
- 【C++】位运算实现加减乘除
- android listview 预加载动画,Android - 使用预加载的数据库填充ListView
- 【算法笔记】Diadem Metric
- 数据分析报表使用指南
- chrome调试工具使用技巧汇总
- 入选全球灯塔工厂 西部数据践行可持续发展承诺
- 英语3500词(十二)Easter主题(2022.1.24)
- 【转】GitHub 优秀的 Android 开源项目
- 入坑esp-01s 1.3寸OLED带农历时钟及天气显示(四)
- 2022年 Q1书单:17本书《可口可乐传》《随机漫步的傻瓜》等 | δ星 丨读书笔记与书单 notes...
- 从Java 9 到 Java 17之Java 11
- 大数据分析数据分析师培训学什么
- oracle建表的时候同时创建主键,外键,注释,约束,索引
- C++ 实现磁盘初始化
- 德州仪器工业4.0产品组合
- 2021-10-23 python第一天