2021-04-05

Spring工程搭建

spring基础包:
1.spring-core:Core模块主要包含Spring框架基本的核心工具类,Spring的其他组件要都要使用到这个包里的类,Core模块是其他组件的基本核心
2.spring-beans:包含访问配置文件、创建和管理bean以及进行IOC/DI操作相关的所有类
3.spring-context:Spring的上下文即IOC容器,通过上下文可以获得容器中的Bean
4.spring-expression:EL表达式语言用于在运行时查询和操纵对象<dependencies> <!-https://mvnrepository.com/artifact/org.springframework/spring-core --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>5.2.13.RELEASE</version> </dependency> <!-https://mvnrepository.com/artifact/org.springframework/spring-beans --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>5.2.13.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-context --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.13.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-expression --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-expression</artifactId> <version>5.2.13.RELEASE</version> </dependency> </dependencies>

核心配置文件

1.:spring的核心配置文件中的各种配置。
spring的核心配置文件的名字 叫做 applicationContext.xml,后期也可以通过配置文件中的配置修改名称,在web.xml中进行如下配置:
<context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring/applicationContext*.xml</param-value> </context-param>

2:核心配置文件中关于dao层的配置。
(1):首先准备db.properties 配置文件,最简单的配置如下。 jdbc.driver=com.mysql.jdbc.Driverjdbc.url=jdbc:mysql://127.0.0.1:3306/demo?characterEncoding=utf-8jdbc.username=rootjdbc.password=123456
(2):然后加载在核心配置文件中加载数据库文件. <context:property-placeholder location="/>

(3):配置数据库连接池,配置类可以用BasicDatasource,也可以用阿里巴巴的配置核心类 DruidDataSource。 <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close"> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> <property name="driverClassName" value="${jdbc.driver}" /> <property name="maxActive" value="10" /> <property name="minIdle" value="5" /> </bean>
后期需要可以在其中添加多个属性配置。
(4):spring和hibernate,和mybatis的整合主要是整合sessionFactory. 和hibernate的一个整合。 <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <!-- 与dataSource --> <property name="dataSource"> <ref bean="dataSource"/> </property></bean>
和mybatis的一个整合. <!-- 让spring管理sqlsessionfactory 使用mybatis和spring整合包中的 --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!-- 数据库连接池 --> <property name="dataSource" ref="dataSource" /> <!-- 加载mybatis的全局配置文件 --> <property name="configLocation" value="classpath:mybatis/SqlMapConfig.xml" /> </bean>
(5):配置文件中关于事务的配置。< !-- 事务管理器 --> !-- 事务管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <!-- 数据源 --> <property name="dataSource" ref="dataSource" /> </bean>
配置通知<!-- 通知 --> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <!-- 传播行为 --> <tx:method name="save*" propagation="REQUIRED" /> <tx:method name="insert*" propagation="REQUIRED" /> <tx:method name="add*" propagation="REQUIRED" /> <tx:method name="create*" propagation="REQUIRED" /> <tx:method name="delete*" propagation="REQUIRED" /> <tx:method name="update*" propagation="REQUIRED" /> <tx:method name="find*" propagation="SUPPORTS" read-only="true" /> <tx:method name="select*" propagation="SUPPORTS" read-only="true" /> <tx:method name="get*" propagation="SUPPORTS" read-only="true" /> </tx:attributes> </tx:advice>
关于切面的配置。<!-- 切面 --> <aop:config> <aop:advisor advice-ref="txAdvice" pointcut="execution(* com.store.service.*.*(..))" /> </aop:config>
关于配置文件中的service层的配置。 扫描包下面所有的service层。 <context:component-scan base-package="com.xiaoao.service"/>
关于注解注入的配置
<mvc:annotation-driven />
(6):在进行配置的时候所需要引入的命名空间。 <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" 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-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/s ... ing-context-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd"> jar包导入的话,可以使用maven管理,非常方便。

项目常用后端代码结构Controller+Service+Dao

  1. Controller层(流程控制层)主要负责具体的业务模块流程的控制
  2. Service层(业务逻辑层)主要负责业务模块的逻辑应用设计
  3. Dao层(数据操作层)主要负责与数据库进行联络的一些任务
  4. 方法调用流程
  5. 以查询操作为例数据流动方向如下图所示:在这里插入图片描述
    Dao层去数据库查询基础数据,查到的基础数据用entity实体类存储Service层调用Dao层方法拿取基础数据加工处理,加工好的数据用vo视图类存储Controller层调用Service层方法拿取数据给前端

Spring IOC & DI

一、Ioc是什么?
控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫“依赖查找”(Dependency Lookup)。通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体,将其所依赖的对象的引用传递给它。也可以说,依赖被注入到对象中。当然,这是百度说的,看了还是不懂,so,复杂的东西简单说控制反转三个问题:1、谁控制谁
2、控制了什么
3、怎么就反转了
第一个问题:谁控制谁,Ioc其实可以把它当做一个容器,一个存储对象的容器,我们开发中的对象都可以交给spring Ioc容器做一个统一的规范管理,就好像是我们每个人都有自己的简历,全部交给人力资源局来管理,Ioc容器就充当一个人力资源局的角色;
第二个问题:控制了什么,既然我们的开发之中的对象已经全部交由Ioc容器来管理了,那我们在获取对象的时候就得由Ioc容器来给我们提供,那么然Ioc容器也就控制了我们实例对象的获取权,就好像我们要去取得一个人的档案,就得由人力资源局提供,人力资源局控制了我们档案的提取;
第三个问题:怎么就反转了,其实说白了就是一个控制权的反转,好比我们需要一个其他人的档案,我们直接去找这个人家要过来,这个事情是我们来做,控制权就在我们手里(程序过程就是classA需要一个classB的实例,就在A类中直接new 一个B的实例来使用),但是现在我们不直接向这个人所要档案了,我们去向资源局去索要这个人的档案,由人力局把档案给我们(程序过程就是classA需要classB的一个实例,然后告诉Ioc容器,我需要B的实例,你给我一个,然后容器把B的实例给classA),现在,弄档案这个事情是资源局在做而不是我们了,这个弄档案的事情的控制权到了资源局手里而非我们自己去弄,Ioc的职责就像是资源局,我们在使用spring框架开发时,就把我们的对象交由spring Ioc容器来管理,我们对实例对象的控制权利发生了一个反转;
二、Ioc容器能干什么,为什么要把对象的控制权交给容器来管理
Ioc是一种设计思想,帮助我们实现程序之间的解耦,设计出耦合性更低更优良的的程序,传统的开发模式在程序类的内部主动的依赖对象(new Object)来实现注入,从而使的类之间高度耦合,有了Ioc容器之后,我们可以把对象的控制权交给容器,让容器为我们创建管理对象,这样,对象之间耦合度变低,程序的架构体系也会更加的灵活;
三、Ioc与DI
看过很多的博客都把Ioc跟DI分开来说,我个人感觉他们的紧密程度非常之大,像是一条工作链必不可少的部分,工作模式又是相辅相成;
什么是DI:依赖注入,在容器运行的时候,扫描所有的依赖关系,并为之动态的注入对应的依赖关系,比如,我们需要某人的档案了,就给人力资源局发一个通知,告诉他我需要领取xxx的档案,然后资源局就把档案给你送过来,我们领取档案的过程就是DI(依赖注入)
DI的几个问题:1、谁依赖谁
2、谁注入了谁
3、注入了什么
第一个问题:1、谁依赖谁,从我们领取档案的流程来看就知道我们依赖于人力资源局,也就是说程序依赖于Ioc容器
第二个问题:2、谁注入了谁,人力资源局把档案给我们,也就是说Ioc容器把对象注入了程序之中(这个过程就是依赖注入)
第三个问题:3、注入了什么,我们向人力资源局要档案然后给了我们,就是容器把我们依赖的对象注入了程序Ioc与DI的关系:他两的关系就像是同一个问题的不同角度的描述,总是那么的紧密相连,理解过上边的自然心里就清晰了
代理模式
什么是代理模式
这里提到了动态代理的概念,首先解释一下代理模式,代理模式是给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用通俗来说就是委托人将整栋楼的空房间委托给代理商管理,代理商在不改变房屋架构的基础上二次装修,打造为青年公寓出租给有租房需求的客户空房间就是原代码,二次装修就是给源代码统一添加功能,租房动作就是对源代码的引用代理模式的意义
##代理模式可以分为静态代理和动态代理:
静态代理
静态代理是由程序员创建或特定工具自动生成源代码,在程序运行之前,代理类就已经编译生成了.class文件。静态代理的优点是可以在符合开闭原则的情况下对目标对象进行功能扩展,缺点则是开发人员需要为每一个服务都得创建代理类,工作量太大,不易管理。同时接口一旦发生改变,代理类也得相应修改动态代理
动态代理
是在程序运行时通过反射机制动态创建的,随用随加载。动态代理常用的有基于接口和基于子类两种方式基于接口的动态代理指的是由JDK官方提供的Proxy类,要求被代理类最少实现一个接口,这种方式大大减少了开发人员的开发任务,减少了对业务接口的依赖,降低了耦合度,缺点就是注定有一个共同的父类叫Proxy,Java的继承机制注定了这些动态代理类们无法实现对class的动态代理,原因是多继承在Java中本质上就行不通基于子类的动态代理指的是由第三方提供的CGLib,CGLib采用了非常底层的字节码技术,其原理是通过字节码技术为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑。但因为采用的是继承,所以要求被代理类不能用final修饰,即不能是最终类

SpringAOP

AOP称为面向切面编程,在程序开发中主要用来解决一些系统层面上的问题,比如日志,事务,权限等待,Struts2的拦截器设计就是基于AOP的思想,是个比较经典的例子。
一 AOP的基本概念
(1)Aspect(切面):通常是一个类,里面可以定义切入点和通知
(2)JointPoint(连接点):程序执行过程中明确的点,一般是方法的调用
(3)Advice(通知):AOP在特定的切入点上执行的增强处理,有before,after,afterReturning,afterThrowing,around
(4)Pointcut(切入点):就是带有通知的连接点,在程序中主要体现为书写切入点表达式(5)AOP代理:AOP框架创建的对象,代理就是目标对象的加强。Spring中的AOP代理可以使JDK动态代理,也可以是CGLIB代理,前者基于接口,后者基于子类
Spring AOP
Spring中的AOP代理还是离不开Spring的IOC容器,代理的生成,管理及其依赖关系都是由IOC容器负责,Spring默认使用JDK动态代理,在需要代理类而不是代理接口的时候,Spring会自动切换为使用CGLIB代理,不过现在的项目都是面向接口编程,所以JDK动态代理相对来说用的还是多一些。
三 基于注解的AOP配置方式
1.启用@AsjectJ支持在applicationContext.xml中配置下面一句:<aop:aspectj-autoproxy />
2.通知类型介绍
(1)Before:在目标方法被调用之前做增强处理,@Before只需要指定切入点表达式即可(2)AfterReturning:在目标方法正常完成后做增强,@AfterReturning除了指定切入点表达式后,还可以指定一个返回值形参名returning,代表目标方法的返回值(3)AfterThrowing:主要用来处理程序中未处理的异常,@AfterThrowing除了指定切入点表达式后,还可以指定一个throwing的返回值形参名,可以通过该形参名来访问目标方法中所抛出的异常对象
(4)After:在目标方法完成之后做增强,无论目标方法时候成功完成。@After可以指定一个切入点表达式
(5)Around:环绕通知,在目标方法完成前后做增强处理,环绕通知是最重要的通知类型,像事务,日志等都是环绕通知,注意编程中核心是一个ProceedingJoinPoint
基于SpringAOP的转账功能四种方法

** --编程式**

`
在这里插/**

  • @Description:转账案例的DAO层接口 * / public interface AccountDao { /* * @param out * :转出账号 * @param money * :转账金额 / public void outMoney(String out, Double money); /* * * @param in * :转入账号 * @param money * :转账金额 */ public void inMoney(String in, Double money); }
  • /**
  • @Description:转账案例的DAO层实现类 / public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao { /* * @param out * :转出账号 * @param money * :转账金额 / @Override public void outMoney(String out, Double money) { String sql = “update account set money = money-? where name = ?”; this.getJdbcTemplate().update(sql, money, out); } /* * @param in * :转入账号 * @param money * :转账金额 / @Override public void inMoney(String in, Double money) { String sql = “update account set money = money+? where name = ?”; this.getJdbcTemplate().update(sql, money, in); } }
    /
  • @Description:转账案例的业务接口 * / public interface AccountService { /* * @param out :转出账号 * @param in :转入账号 * @param money :转账金额 */ public void transfer(String out,String in,Double money); }
  • /**
  • @Description:转账案例的业务层实现类 / public class AccountServiceImpl implements AccountService { // 注入转账的DAO private AccountDao accountDao; // 注入事务管理的模板 private TransactionTemplate transactionTemplate; /* * @param out * :转出账号 * @param in * :转入账号 * @param money * :转账金额 */ @Override public void transfer(final String out, final String in, final Double money) { // 未经事务控制的业务处理操作,如果过程中出异常,则导致前面的操作能完成,后面的不能,即转账成功但未收到转账款 // accountDao.outMoney(out, money); // int i = 1/0; // accountDao.inMoney(in, money); transactionTemplate.execute(new TransactionCallbackWithoutResult() { @Override protected void doInTransactionWithoutResult( TransactionStatus transactionStatus) { accountDao.outMoney(out, money); // int i = 1 / 0;//事务控制,即出现异常,该段内代码都执行失效 accountDao.inMoney(in, money); } }); } public void setAccountDao(AccountDao accountDao) { this.accountDao = accountDao; } public void setTransactionTemplate(TransactionTemplate transactionTemplate) { this.transactionTemplate = transactionTemplate; } } 入代码片

` –基于TransactionProxyFactoryBean的方式

`
public class AccountServiceImpl implements AccountService {
// 注入转账的DAO private AccountDao accountDao; /** * @param out * :转出账号 * @param in * :转入账号 * @param money * :转账金额 */ @Override public void transfer(String out, String in, Double money) { accountDao.outMoney(out, money); // int i = 1/0; accountDao.inMoney(in, money); } public void setAccountDao(AccountDao accountDao) { this.accountDao = accountDao; } }

<context:property-placeholder location=“classpath:jdbc.properties”/> PROPAGATION_REQUIRED `
–基于XML配置

public class AccountServiceImpl implements AccountService { 
 // 注入转账的DAO  private AccountDao accountDao;   /**  * @param out  *  :转出账号  * @param in  *  :转入账号  * @param money  *  :转账金额  */  @Override  public void transfer(String out, String in, Double money) {  accountDao.outMoney(out, money);  // int i = 1/0;  accountDao.inMoney(in, money);   }   public void setAccountDao(AccountDao accountDao) {  this.accountDao = accountDao;  } } 
 <!-- 引入外部的属性文件 --> 
 <context:property-placeholder location="classpath:jdbc.properties"/>   <!-- 配置c3p0连接池 -->  <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">  <property name="driverClass" value="${jdbc.driverClass}" />  <property name="jdbcUrl" value="${jdbc.url}" />  <property name="user" value="${jdbc.username}" />  <property name="password" value="${jdbc.password}" />  </bean>   <!-- 配置业务层类 -->  <bean id="accountService" class="com.zs.spring.demo3.AccountServiceImpl">  <property name="accountDao" ref="accountDao" />  </bean>   <!-- 配置DAO类(简化,会自动配置JdbcTemplate) -->  <bean id="accountDao" class="com.zs.spring.demo3.AccountDaoImpl">  <property name="dataSource" ref="dataSource" />  </bean>   <!-- ==================================3.使用XML配置声明式的事务管理,基于tx/aop=============================================== -->   <!-- 配置事务管理器 -->  <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  <property name="dataSource" ref="dataSource" />  </bean>   <!-- 配置事务的通知 -->  <tx:advice id="txAdvice" transaction-manager="transactionManager">  <tx:attributes>   <!--   propagation :事务传播行为   isolation :事务的隔离级别   read-only :只读   rollback-for:发生哪些异常回滚   no-rollback-for :发生哪些异常不回滚   timeout :过期信息   -->   <tx:method name="transfer" propagation="REQUIRED"/>  </tx:attributes>  </tx:advice>   <!-- 配置切面 -->  <aop:config>  <!-- 配置切入点 -->  <aop:pointcut expression="execution(* com.zs.spring.demo3.AccountService+.*(..))" id="pointcut1"/>  <!-- 配置切面 -->  <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut1"/>  </aop:config> 
 

** --基于注解**

/** 
 * @Transactional中的的属性 propagation :事务的传播行为 isolation :事务的隔离级别 readOnly :只读  *   rollbackFor :发生哪些异常回滚 noRollbackFor :发生哪些异常不回滚  *   rollbackForClassName 根据异常类名回滚  */ @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, readOnly = false) public class AccountServiceImpl implements AccountService {  // 注入转账的DAO  private AccountDao accountDao;   /**  * @param out  *  :转出账号  * @param in  *  :转入账号  * @param money  *  :转账金额  */  @Override  public void transfer(String out, String in, Double money) {  accountDao.outMoney(out, money);  // int i = 1/0;  accountDao.inMoney(in, money);  }   public void setAccountDao(AccountDao accountDao) {  this.accountDao = accountDao;  } } 
 * <!-- 引入外部的属性文件 --> 
 <context:property-placeholder location="classpath:jdbc.properties"/>   <!-- 配置c3p0连接池 -->  <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">  <property name="driverClass" value="${jdbc.driverClass}" />  <property name="jdbcUrl" value="${jdbc.url}" />  <property name="user" value="${jdbc.username}" />  <property name="password" value="${jdbc.password}" />  </bean>   <!-- 配置业务层类 -->  <bean id="accountService" class="com.zs.spring.demo4.AccountServiceImpl">  <property name="accountDao" ref="accountDao" />  </bean>   <!-- 配置DAO类(简化,会自动配置JdbcTemplate) -->  <bean id="accountDao" class="com.zs.spring.demo4.AccountDaoImpl">  <property name="dataSource" ref="dataSource" />  </bean>   <!-- ==================================4.使用注解配置声明式事务============================================ -->   <!-- 配置事务管理器 -->  <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  <property name="dataSource" ref="dataSource" />  </bean>   <!-- 开启注解事务 -->  <tx:annotation-driven transaction-manager="transactionManager"/> 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值