Spring-1-(简介及HelloWord)
一:Spring简介
Spring 框架宗旨:不重新发明技术,让原有技术使用起来更加方便.
Spring核心功能:
1.AOP:面向切面编程
2.Ioc/Di:控制反转/依赖注入
3.声明式事务
Spring框架RunTime(运行时环境)
Spring中的容器(Container):
Spring 框架中重要概念
容器(Container): Spring 当作一个大容器.
BeanFactory 接口.老版本.
ApplicationContext 接口,新版本,是 BeanFactory 子接口
BeanFactory 的功能在 ApplicationContext 中都有
Spring拆分jar包:
Spring3 开始把 Spring 框架的功能拆分成多个 jar. 7.1 Spring2 及以前就一个 jar(优点:可根据不同的需求导入不同的jar,而不需将Spring中的60多个jar都加载进去)
解析框架:
test: spring 提供测试功能
Core Container:核心容器.Spring 启动最基本的条件. (将spring跑起来至少有这些东西)
Beans : Spring 负责创建类对象并管理对象
Core: 核心类(类库)
Context: 上下文参数.获取外部资源或这管理注解等
SpEl: expression.jar
AOP: 实现 aop 功能需要依赖
Aspects: 切面 AOP 依赖的包
Data Access/Integration : spring 封装数据访问层相关内容
JDBC : Spring 对 JDBC 封装后的代码. 5.5.2 ORM: 封装了持久层框架的代码.例如 Hibernate
Transactions:对应 spring-tx.jar,声明式事务使用. 5.6 WEB:需要 spring 完成 web 相关功能时需要. 5.6.1 例如:由 tomcat 加载 spring 配置文件时需要有 spring-web包
注意:Spring运行并不依赖与Web容器(tomcat等等),jar包依旧可以运行,但是spring提供了web的jar包,所以也可以使用web容器来运行
二:核心功能
一)IoC
1 中文名称:控制反转
2.英文名称:(Inversion of Control)
3.IoC 是什么?
3.1 IoC 完成的事情原先由程序员主动通过 new 实例化对象事情,转交给 Spring 负责.
3.2 控制反转中控制的是谁:
控制类的对象.
3.3 控制反转中反转指的是:
原来有程序员管理的类的对象转交给 Spring 负责管理.
3.4 IoC 最大的作用:解耦.
3.4.1 程序员不需要管理对象.解除了对象管理和程序员之间的耦合.
- //以往我们需要自己手动的创建对象,并进行使用
- User user = new User();
- String address = user.getAddress();
- //现在我们只需要将spring容器中的对象拿出来使用就好了
- @Autowired
- User user;
- String address1 = user.getAddress();
IoC容器有两种:
BeanFactory:
简介:
基础类型的IoC容器,由org.springframework.beans.factory.BeanFactory接口定义,并提供了完整的IoC服务支持;
BeanFactory是一个管理Bean的工程,负责初始化各种Bean并调用他们的生命周期方法。
实现:
org.springframework.beans.factory.xml.XmlBeanFactory,根据xml配置文件中的定义来装配Bean
ApplicationContext:(也就是我们配置的ApplicationContext.xml)
简介:
是BeanFactory的子接口,也被称为应用上下文,由org.springframework.context.ApplicationContext提供,
他提供BeanFactory所有的功能,并且加强了BeanFactory的功能,体现在Context包使用分层和有继承关系的上下文类:
1.MessageSource,提供对i18n消息的访问;
2.资源访问,例如URL和文件
3.事件传递给实现了ApplicationListener接口的Bean;
4.载入多个有集成关系的上下文类,使每一个上下文类都专注于一个特定的层次,
几乎所有的场合都是用ApplicationContext而非底层的BeanFactory
创建ApplicationContext接口实例(创建IoC容器):
方式一:(从类路径中的xml文件载入上下文定义信息)
ApplicatonContext applicationcontext=new ClassPathXmlApplicationContext("applicationContext.xml")
方式二:(从文件路径中的xml文件载入上下文定义信息)
ApplicatonContext applicationcontext=new FileSystemXmlApplicationContext("F:\\workspace\\applicationContext.xml")
这里创建的是一个web工程但是使用的main方法执行也可以放进tomcat中运行)
所依赖的jar包(核心包之外还要加一个日志包commons-logging.jar):
- <bean class="com.xpl.model.User" id="user">
- public class Text {
- public static void main(String[] args) {
- // 将applicationContext加载进去,初始化spring容器
- // spring初始化的时候就会将容器中的所有组件初始化,这个时候对象已将创建
- // 他是通过类的无参构造进行初始化的
- ClassPathXmlApplicationContext cxt = new ClassPathXmlApplicationContext("applicationContext.xml");
- // 获取spring容器中的组件
- // 方式有三种:
- // 方式一:通过id获取,但是要强转
- // User user = (User) cxt.getBean("user");
- // 方式二:通过id和类获取
- User user = cxt.getBean("user4", User.class);
- System.out.println(user);
- // 方式三:通过class类获取,有个缺陷,加入spring中使用这个类创建了多个实例,就会冲突,找不到
- User bean = cxt.getBean(User.class);
- String[] beanDefinitionNames = cxt.getBeanDefinitionNames();
- // 可以看到spring容器中所有的组件名字
- for(int i=0;i<beanDefinitionNames.length;i++){
- System.out.println(beanDefinitionNames[i]);
- }
- }
- }
Spring创建实例的三种方式:
1).构造器创建
1.1.无参构造器(默认)
1.2.有参构造
具体使用参照下边的代码注释
2).实例工厂
3).静态工厂.
- <!--通过构造器注入bean-->
- <bean class="com.xpl.model.User" id="user">
- <constructor-arg index="0" value="张三"/>
- <constructor-arg index="1" value="27"/>
- </bean>
- <!--结果-->
- <!--有参构造String name, int age-->
- <!--User{name='张三', age=27}-->
- <bean class="com.xpl.model.User" id="user1">
- <constructor-arg name="name" value="李四"/>
- <constructor-arg name="age" value="27"/>
- </bean>
- <!--结果-->
- <!--有参构造int age,String name-->
- <!--User{name='李四', age=27}-->
- <!--发现:走的是后边(有两个有参构造,第二个有参构造)-->
- <!--是因为通过有参构造,name属性赋值时候,执行参数相同的构造器的最后一个)-->
- <!--这个时候就需要使用参数中的index或者type来精准定位-->
- <!--注意不需要全都写,配合使用只要能定位到某个构造器就可以-->
- <bean class="com.xpl.model.User" id="user2">
- <constructor-arg name="name" index="0" value="王五"/>
- <constructor-arg name="age" value="27"/>
- </bean>
- <!--结果-->
- <!--有参构造String name, int age-->
- <!--User{name='王五', age=27}-->
- <!--实例工厂创建-->
- <!--实例工厂需要实例化,所以先注入进来-->
- <bean class="com.xpl.model.UserFactory" id="userFactory"/>
- <!--指定实例工厂是哪一个,在指定工厂方法是哪一个-->
- <bean factory-bean="userFactory" factory-method="creatPeople" id="user3"/>
- <!--静态工厂创建-->
- <bean class="com.xpl.model.UserStaticFactory" factory-method="creatPeople" id="user4"/>
对象属性赋值:
1).构造方法注入(上边已经演示过了参考)
2).通过set方法注入
基本数据类型:
复杂数据类型:
- <bean class="com.xpl.model.User" id="user">
- <!--基本数据类型-->
- <property name="name" value="赵六"/>
- <!--数组-->
- <property name="arr">
- <array>
- <value>1</value>
- <value>2</value>
- <value>3</value>
- </array>
- </property>
- <!--如果list中只有一个值也可以这样写-->
- <!--<property name="arr" value="1"/>-->
- <!--引用数据类型,引用上边的cat-->
- <property name="cat" ref="cat"/>
- <!--list-->
- <property name="list">
- <list>
- <value>5</value>
- <value>6</value>
- <value>7</value>
- </list>
- </property>
- <!--如果list中只有一个值也可以这样写-->
- <!--<property name="list" value="1"/>-->
- <!--map-->
- <property name="map">
- <map>
- <entry key="1" value="2"/>
- <entry key="2" value="2"/>
- <entry key="3" value="2"/>
- </map>
- </property>
- <property name="set">
- <set>
- <value>1</value>
- <value>2</value>
- <value>3</value>
- </set>
- </property>
- <property name="properties">
- <props>
- <prop key="1">1</prop>
- <prop key="2">2</prop>
- <prop key="3">3</prop>
- </props>
- </property>
- </bean>
二)DI
1. DI:中文名称:依赖注入
2. 英文名称((Dependency Injection)
3. DI 是什么?
3.1 DI 和 IoC 是一样的
3.2 当一个类(A)中需要依赖另一个类的对象时,把 B 赋值给 A 的过程就叫做依赖注入.(注入:就是给spring容器中的bean赋值的过程;当Bean中的某个属性是另一个Bean时,把这个Bean以属性的方式注
入进去就是依赖注入,广义上描述他就是Aop,狭义上描述就是将一个Bean作为了另外一个Bean的属性)
- //首先有一个bean,这个Bean就是下边Bean的一个属性
- <bean class="com.xpl.model.User" id="user">
- <property name="cat" ref="cat"/>
- </bean>
- <bean class="com.xpl.model.Cat" id="cat">
- //这个Bean中的属性是一个Bean
- <property name="name" value="小白猫"/>
- </bean>
- public class User {
- private Cat cat;
- private Properties properties;
- }
- public class Cat {
- private String name;
- }
三)AOP
1.AOP:中文名称面向切面编程
2.英文名称:(Aspect Oriented Programming)
3.正常程序执行流程都是纵向执行流程
3.1 又叫面向切面编程,在原有纵向执行流程中添加横切面
3.2 不需要修改原有程序代码
3.2.1 高扩展性
3.2.2 原有功能相当于释放了部分逻辑.让职责更加明确.
概念:(原理:动态代理)
在程序原有纵向执行流程中,针对某一个或某一些方法添加通知,形成横切面过程就叫做面向切面编程.
主要体现在事务处理,日志管理,权限控制,异常处理等方面,提高代码的可维护性。
原有功能: 连接点, pointcut(在某个方法前织入,这个方法就叫连接点)
增加的部分叫做通知(增强Advice)
前置通知: 在切点之前执行的功能. before advice
后置通知: 在切点之后执行的功能,after advice
异常通知.throws advice
环绕通知:
所有切点+通知叫做切面.
织入: 把切面嵌入到原有功能的过程叫做织入
重要:spring声明式事务是基于aop实现的,事务一般是用在service上的,有了事务service中一旦出现异常就会回滚,
所以不建议在service中使用try-catch,因为使用try-catch之后aop就捕获不到异常,声明式事务就失效了
java原生动态代理:
- public interface Calculate {
- public int add(int a,int b);
- public int min(int a,int b);
- }
- public class Calculateimpl implements Calculate {
- @Override
- public int add(int a, int b) {
- return a+b;
- }
- @Override
- public int min(int a, int b) {
- return a-b;
- }
- }
- public class ProxyFactory {
- //创建代理对象
- public Object createMyCalculate(Object obj){
- //Proxy是java反射中的一个类 obj.getClass().getClassLoader()获取类加载器 实现的接口
- return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), new InvocationHandler() {
- @Override
- //代理的那个对象(传入的) 要处理的方法 传入的参数
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
- System.out.println("star");
- //调用方法并执行
- Object invoke = method.invoke(obj, args);
- System.out.println("end");
- return invoke;
- }
- });
- }
- }
- public class Text {
public static void main(String[] args) {
ProxyFactory proxyFactory=new ProxyFactory();
Calculateimpl calculateimpl=new Calculateimpl();
Calculate calculate=(Calculate)proxyFactory.createMyCalculate(calculateimpl));
calculate.add(1,3);
}
}
Spring中aop实现:
XML方式配置:
- /**
- * 定义advice
- */
- public class Advice {
- public void before(){
- System.out.println("前");
- }
- public void mythrow(Exception e){
- // 还需要配置xml才可以打印出异常信息
- System.out.println("异常"+e.getMessage());
- }
- public void after(){
- System.out.println("后");
- }
- public void aftering(){
- System.out.println("aftering");
- }
- public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
- System.out.println("执行环绕通知");
- System.out.println("环绕-前置");
- // 返回值
- Object proceed = proceedingJoinPoint.proceed();
- System.out.println(proceed);
- System.out.println("环绕-后置");
- return proceed;
- }
- }
- public class Demo {
- public int min(int i,int j){
- return i+j;
- }
- }
- public class Text {
- public static void main(String[] args) {
- ClassPathXmlApplicationContext cxt = new ClassPathXmlApplicationContext("applicationContext.xml");
- Demo demo = cxt.getBean("demo", Demo.class);
- demo.min(1,5);
- }
- }
- <!--将要被增强的对象注入进来-->
- <bean class="com.xpl.test.Demo" id="demo"/>
- <!--将advice注入进来-->
- <bean class="com.xpl.advice.Advice" id="advice"/>
- <aop:config>
- <!--定义切点:就是要在哪个方法上增强-->
- <aop:pointcut id="min" expression="execution(int com.xpl.test.Demo.min(int ,int ))"/>
- <!--定义切面:切点+增强-->
- <!--引用的就是上边注入进来的增强Bean-->
- <aop:aspect ref="advice">
- <!--这几个增强是有顺序的特别是异常aftering和after-->
- <!--通知类型 增强方法名(增强类中的) 被增强的方法(上边定义的切点)-->
- <!--after和after-returning的区别:-->
- <!--after无论是否抛出异常都会执行-->
- <!--after-returning必须正确执行才会执行-->
- <aop:after method="after" pointcut-ref="min"/>
- <aop:after-returning method="aftering" pointcut-ref="min"/>
- <aop:after method="before" pointcut-ref="min"/>
- <!--必须和增强类中异常方法中参数的异常名相同-->
- <aop:after-throwing method="mythrow" pointcut-ref="min" throwing="e"/>
- <aop:around method="around" pointcut-ref="min"/>
- </aop:aspect>
- </aop:config>
通配符*
在定义切点的时候可以使用*通配符精确定位切点
他支持一级包名
- <aop:pointcut id="min" expression="execution(int com.xpl.test.Demo.min(int ,int ))"/>
- 表示com包下的所有包中的所有方法
- <aop:pointcut id="min" expression="execution(* com.*.*.*.*(* ,* ))"/>
四)自动注入
前提:Spring全局配置文件中
看代码理解:
两个类A和B需要交给Spring管理
B中有个属性是对象A
非自动注入:自己写自己的property给属性赋值,或使用ref
自动注入:在bean标签上使用autowire属性
原理:Byname去判断我需要注入的属性名在spring容器中是否存在id名称一样的,存在就直接注入给他,
Bytype是去找class
Constructor:需要实体类中有有参构造方法,并且参数名称要和xml中的name一样
- public class B {
- private String name;
- private A a;
- public class A {
- private String name;
- 没有自动注入
<bean class="com.xpl.model.A" id="a">- <property name="name" value="aaa"/>
- </bean>-->
- <bean class="com.xpl.model.B" id="b">
- <property name="name" value="bbbbb"/>
- <property name="A" ref="a"/>
- </bean>
- 自动注入
- <bean class="com.xpl.model.A" id="a">
- <property name="name" value="aaa"/>
- </bean>
- <bean class="com.xpl.model.B" id="b" autowire="byName">
- <property name="name" value="bbbbb"/>
- </bean>
也可以配置为全局的
- <?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/beans
- http://www.springframework.org/schema/beans/spring-beans.xsd"
- default-autowire="byName">
五:加载配置文件
注意:通过配置文件健在内容的时候要注意使用下边高亮部分
原因是:实例化先后顺序造成的,以免在实例化完成之后加载配置文件就加载不进去了
- db.driver=com.mysql.jdbc.Driver
- db.username=root
- db.password=root
- db.url=jdbc:mysql:///test?useUnicode=true&characterEncoding=UTF-8
- <?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 http://www.springframework.org/schema/context/spring-context.xsd">
- <context:property-placeholder location="classpath:db.properties"/>
- <!--配置数据源-->
- <bean class="org.springframework.jdbc.datasource.DriverManagerDataSource" id="dataSource">
- <property name="driverClassName" value="${db.driver}"/>
- <property name="username" value="${db.username}"/>
- <property name="password" value="${db.password}"/>
- <property name="url" value="${db.url}"/>
- </bean>
- <!--创建sqlSessionFactory-->
- <bean class="org.mybatis.spring.SqlSessionFactoryBean" id="factory">
- <!--创建sqlSession需要有数据库连接,na那么就引用上边的数据源-->
- <property name="dataSource" ref="dataSource"/>
- <property name="typeAliasesPackage" value="com.xpl.model"/>
- </bean>
//扫描配置mapper.xml文件
<bean class="org.mybatis.spring.SqlSessionFactoryBean" id="sqlSessionFactory">- <property name="dataSource" ref="dataSource"/>
- <property name="typeAliasesPackage" value="com.xpl.model"/>
- <property name="mapperLocations">
- <list>
- <value>classpath*:com/xpl/mapper/*.xml</value>
- </list>
- </property>
- </bean>
- <!--扫描器,加载mapper接口-->
- <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
- //配置这一句就可以mapper接口和mapper.xml不写在一个文件夹了
- <property name="basePackage" value="com.xpl.mapper"/>
- <property name="sqlSessionFactoryBeanName" value="factory"/>
- <!--<property name="sqlSessionFactory" ref="factory"/>-->
- </bean>
- </beans>
六:从配置文件中取值
- people.name=xupeilei
- 两种方式,将bean交给Spring容器!!!这是关键,要想去spring容器中的全局的值,就一定要把这个Bean交给Spring管理!!!!!
方式一:直接配置进去- <bean class="com.xpl.model.People" id="people"/>
- 方式二:通过包扫描
- <context:component-scan base-package="com.xpl.model"/>
- public class People {
name这个属性名和取值时的name名没有必然关系,可以不一样- @Value("${people.name}")
- private String name;
七:Scope属性
默认单例
八:声明式事务
1.编程式事务:
1.1 由程序员编程事务控制代码. 1.2 OpenSessionInView 编程式事务
2.声明式事务:
2.1 事务控制代码已经由 spring 写好.程序员只需要声明出哪些方法需要进行事务控制和如何进行事务控制.
3.声明式事务都是针对于 Service 类下方法的.
4.事务管理器基于通知(advice)的.
- <?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" xmlns:tx="http://www.springframework.org/schema/tx"
- xmlns:aop="http://www.springframework.org/schema/aop"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">- <!--配置数据库链接-->
- <!--引入数据库连接信息-->
- <context:property-placeholder location="classpath:db.properties"/>
- <!--配置数据库里连接池-->
- <bean class="com.alibaba.druid.pool.DruidDataSource" id="dataSource">
- <property name="url" value="${db.url}"/>
- <property name="username" value="${db.username}"/>
- <property name="password" value="${db.password}"/>
- </bean>
<!--配置mybatis-->- <!--配置mapper-->
- <bean class="org.mybatis.spring.SqlSessionFactoryBean" id="sqlSessionFactory">
- <property name="dataSource" ref="dataSource"/>
- <property name="typeAliasesPackage" value="com.xpl.model"/>
- <property name="mapperLocations">
- <list>
- <value>classpath*:com/xpl/mapper/*.xml</value>
- </list>
- </property>
- </bean>
- <!--自动获取getXXX(mapper.xlass)-->
- <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
- <!--获取那个接口 value就是上边配的SqlSessionFactoryBean-->
- <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
- <!--接口所在的文件夹 这里配置完了就不需要将接口和mapper文件放一个文件夹了-->
- <property name="basePackage" value="com.xpl.mappering"/>
- </bean>
- <!--配置事务-->
- <bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="dataSourceTransactionManager">
- <property name="dataSource" ref="dataSource"/>
- </bean>
- <tx:advice id="txAdvice" transaction-manager="dataSourceTransactionManager">
- <tx:attributes>
- <tx:method name="add*"/>
- <tx:method name="upd*"/>
- <tx:method name="del*"/>
- <tx:method name="sel*"/>
<tx:method name="*" read-only="true"/>- </tx:attributes>
- </tx:advice>
- <aop:config>
- <aop:pointcut id="pc1" expression="execution(* com.xpl.service.*.*(..))"/>
- <aop:advisor advice-ref="txAdvice" pointcut-ref="pc1"/>
- </aop:config>
- </beans>
九:事务传播行为
- <tx:method name="add*" read-only="" propagation=""/>
readonly=”boolean” 是否是只读事务.
1 如果为 true,告诉数据库此事务为只读事务.数据化优化,会对性能有一定提升,所以只要是查询的方法,建议使用此数据.
2 如果为 false(默认值),事务需要提交的事务.建议新增,删除,修改.
propagation 控制事务传播行为.
1当一个具有事务控制的方法被另一个有事务控制的方法调用后,需要如何管理事务(新建事务?在事务中执行?把事务挂起?报异常?)
REQUIRED (默认值): 如果当前有事务,就在事务中执行,如果当前没有事务,新建一个事务.
SUPPORTS:如果当前有事务就在事务中执行,如果当前没有事务,就在非事务状态下执行.
MANDATORY:必须在事务内部执行,如果当前有事务,就在事务中执行,如果没有事务,报错.
REQUIRES_NEW:必须在事务中执行,如果当前没有事务,新建事务,如果当前有事务,把当前事务挂起.
NOT_SUPPORTED:必须在非事务下执行,如果当前没有事务,正常执行,如果当前有事务,把当前事务挂起.
NEVER:必须在非事务状态下执行,如果当前没有事务,正常执行, 如果当前有事务,报错.
NESTED:必须在事务状态下执行.如果没有事务,新建事务,常执行,如果当前有事务,把当前事务挂起.
十:事务隔离级别
- <tx:method name="add*" isolation="DEFAULT"/>
脏读:
一个事务(A)读取到另一个事务(B)中未提交的数据,另一个事务中数据可能进行了改变,此时 A事务读取的数据可能和数据库中数据是不一致的,此时认为数据是脏数据,读取脏数据过程叫做脏读
解释:A从数据库读出一条数据(aaa),并修改为(bbb)没有提交只是flush到内存中,这时B读到了内存中的数据(bbb),但是数据库中数据依旧是(aaa),B读到的就是脏数据
. 不可重复读:
主要针对的是某行数据.(或行中某列)
主要针对的操作是修改操作.
两次读取在同一个事务内
当事务 A 第一次读取事务后,事务 B 对事务 A 读取的淑君进行修改,事务 A 中再次读取的数据和之前读取的数据不一致,过程不可重复读.
解释:张三盘点了仓库现存50吨大豆,然后他准备卖给特朗普,这时他老婆在他不知道的情况卖给了金三胖,张三合同签回来准备发货发现大豆没有了
幻读:
主要针对的操作是新增或删除
两次事务的结果.
事务 A 按照特定条件查询出结果,事务 B 新增了一条符合条件的数据.事务 A 中查询的数据和数据库中的数据不一致的,事务 A 好像出现了幻觉,这种情况称为幻读.
isolation=”” 事务隔离级别在多线程或并发访问下如何保证访问到的数据具有完整性的.
DEFAULT:
默认值,由底层数据库自动判断应该使用什么隔离界别
READ_UNCOMMITTED: 可以读取未提交数据,可能出现脏读,不重复读,幻读.
效率最高.
READ_COMMITTED:只能读取其他事务已提交数据.可以防止脏读,可能出现不可重复读和幻读.
REPEATABLE_READ: 读取的数据被添加锁,防止其他事务修改此数据,可以防止不可重复读.脏读,可能出现幻读.
SERIALIZABLE: 排队操作,对整个表添加锁.一个事务在操作数据时,另一个事务等待事务操作完成后才能操作这个表.
最安全的
效率最低的.
十一:事务回滚
- <tx:method name="add*"rollback-for="" no-rollback-for=""/>
rollback-for=”异常类型全限定路径”
当出现什么异常时需要进行回滚
建议:给定该属性值.
手动抛异常一定要给该属性值.
no-rollback-for=””
当出现什么异常时不滚回事务.
十二:注解
1. @Component 创建类对象,相当于配置<bean/>
2. @Service 与@Component 功能相同.
2.1 写在 ServiceImpl 类上.
3. @Repository 与@Component 功能相同.
3.1 写在数据访问层类上.
4. @Controller 与@Component 功能相同.
4.1 写在控制器类上.
5. @Resource(不需要写对象的 get/set)(其实相当于对自动注入的补充:因为使用注解的方式auto就不生效了,但是我们还要在类中放入属性,就将这个类放进去)
5.1 java 中的注解
5.2 默认按照 byName 注入,如果没有名称对象,按照 byType 注入
5.2.1 建议把对象名称和 spring 容器中对象名相同
6. @Autowired(不需要写对象的 get/set)
6.1 spring 的注解
6.2 默认按照 byType 注入.
7. @Value() 获取 properties 文件中内容
8. @Pointcut() 定义切点
9. @Aspect() 定义切面类
10. @Before() 前置通知
11. @After 后置通知
12. @AfterReturning 后置通知,必须切点正确执行
13. @AfterThrowing 异常通知
14. @Arround 环绕通知
十三:java配置类
可以不使用applicationContext.xml来配置属性而是使用一个java类来替代
@Configuration
@Componentscan:默认扫描当前包及子包的子包。。
@Componentscan(basePackages=“com.xpl.model”)设置扫描哪一个包
@Bean
十四:多数据源
Spring-1-(简介及HelloWord)的更多相关文章
- [原创]java WEB学习笔记96:Spring学习---Spring简介及HelloWord
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- Spring 系列: Spring 框架简介 -7个部分
Spring 系列: Spring 框架简介 Spring AOP 和 IOC 容器入门 在这由三部分组成的介绍 Spring 框架的系列文章的第一期中,将开始学习如何用 Spring 技术构建轻量级 ...
- Spring MVC简介
Spring MVC简介 Spring MVC框架是有一个MVC框架,通过实现Model-View-Controller模式来很好地将数据.业务与展现进行分离.从这样一个角度来说,Spring MVC ...
- Spring 系列: Spring 框架简介(转载)
Spring 系列: Spring 框架简介 http://www.ibm.com/developerworks/cn/java/wa-spring1/ Spring AOP 和 IOC 容器入门 在 ...
- Spring Boot简介
Spring Boot简介 Spring Boot是为了简化Spring开发而生,从Spring 3.x开始,Spring社区的发展方向就是弱化xml配置文件而加大注解的戏份.最近召开的SpringO ...
- Spring Cloud微服务笔记(二)Spring Cloud 简介
Spring Cloud 简介 Spring Cloud的设计理念是Integrate Everything,即充分利用现有的开源组件, 在它们之上设计一套统一的规范/接口使它们能够接入Spring ...
- Spring AOP 简介
Spring AOP 简介 如果说 IoC 是 Spring 的核心,那么面向切面编程就是 Spring 最为重要的功能之一了,在数据库事务中切面编程被广泛使用. AOP 即 Aspect Orien ...
- 第63节:Java中的Spring MVC简介笔记
前言 感谢! 承蒙关照~ Java中的Spring MVC简介笔记 MVC简介 Spring MVC 基本概念 Spring MVC 项目搭建 maven 使用Spring MVC进行开发 实现数据绑 ...
- Spring Boot 简介
作者其他Spring系列文章 Spring Framework简介 Spring框架快速入门 Spring Boot愿景 Spring Boot愿景就是让我们创建可运行的.独立的.基于Spring的 ...
- Spring Boot从入门到精通之:一、Spring Boot简介及快速入门
Spring Boot Spring Boot 简介 Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来 ...
随机推荐
- C# WINFORM 编程中,选择**文件夹**而不是文件的方法(转)
我们选择文件可以用 OpenFileDialog ,但是文件夹有两种方法. 法一: 用C#的FolderNameEditor类的子类FolderBrowser类来实现获取浏览文件夹对话框的功能.下面来 ...
- 改造 Android 官方架构组件 ViewModel
前言 Android 官方架构组件在今年 5 月份 Google I/O 大会上被公布, 直到 11 月份一直都是测试版, 由于工作比较繁忙, 期间我只是看过类似的文章, 但没有在实际项目中使用过, ...
- Confluence 6 数据模型
本文档提供了 Confluence 的数据结构视图(schema )和数据模型概念上的的概述. 备注: Hibernate 的映射文件是针对 Confluence 数据模型的直接描述.在系统中的 Co ...
- 基于DBUtils实现数据库连接池
小知识: 1.子类继承父类的三种方式 class Dog(Animal): #子类 派生类 def __init__(self,name,breed, life_value,aggr): # Anim ...
- WPA-PSK无线网络密码破解原理
1.基于WPA2的加密标准还是能够被破解,一个弊端是他无法避开时候双方验证的模式来认证取得合法性的连接,当我们抓取足够多得双反认证的数据包之后就可以破解密码.之前很多片的博客写了如何破解这种加密的秘钥 ...
- CSS----布局不理解
正常情况 正常显示 如果往div标签中添加汉字 出现显示(不理解) 解决方式 加上vertical-align:top
- 使用gulp进行代码压缩
gulp是一个很不错的前端自动化工具,可以帮我们完成一些重复性操作,比如html.css和js代码的压缩.合并.混淆等,虽然这些操作可以通过一些在线工具帮我们实现,但不断重复地复制粘贴肯定比不上一句命 ...
- cf round546 cde
第一题会卡一下同时用set和cin.. 其他的注意下矩阵对角线下标的应用即可 #include<bits/stdc++.h> using namespace std; #define ma ...
- poj1155 依赖背包
/* 依赖背包 dp[i][j]表示i结点为根的树选择j个用户时的最大剩余费用 即背包容量是j,价值是最大费用 */ #include<iostream> #include<cstr ...
- requests中get和post传参
get请求 get(url, params=None, **kwargs) requests实现get请求传参的两种方式 方式一: import requests url = 'http://www. ...