SSM Spring篇

Spring框架

Spring是一个基于IOC和AOP的结构J2EE系统的框架(容器)

ioc

IOC容器 控制的实现方式 是Spring的基础,Inversion Of Control,是一种设计思想,di依赖注入是实现ioc的一种方式

是一种通过描述(xml或者注解)并通过第三方或获取对象的方式

  • ①多态实现 耦合度太高 传统开发 需求发生更改的时候需要修改impl下的东西
public interface UserDao{void getUser()}     					//UserDao

puclic class UserDaoImpl implements UserDao{
	public void getUser(){
		System.out.println()
		}
	}
public interface UserService{void getUser()}                  //UserService

puclic class UserServiceImpl implements UserService{
	UserDao userDao=new UserDaoImpl();
	public void getUser(){
		UserDao.getUser();
	}
}

//用户实际上调用的是dao层
UserService userservice = new UserServiceImpl();  
userService.getUser();
  • ②创建一个set接口

    Service的修改 接口实现降低耦合度

    Private UserDao userDao;
    private void setUserDao(UserDao,userDao){this.userDao = userDao;}
    

    之前程序主动创建对象 控制权在程序员手上

    set注入后 程序不在具有主动性 而是变成了被动的接受对象

    这是ioc的原型 set方法是spring的底层,

③xml实现

ioc创建对象的方式
  • 默认是用无参构造方法
  • 有参的方式创建对象

在这里插入图片描述

在配置文件加载的时候 容器中管理的对象已经初始化了

  • 别名

    <alias name="user" alias="userNew"/>
    

    id bean的唯一标识符 class bean对象所对应的全限定名 name也可以取别名

    applicationcontext相当于总的配置文件 该文件下import可以导入其他的配置文件 相当于交给spring管理

DI

依赖注入:构造器注入 set注入

	<bean id="student" class="com.kuang.pojo.Student">
        <!--第一种,普通值注入,value-->
        <property name="name" value="樊帅"/>

        <!--第二种,Bean注入,ref-->
        <property name="address" ref="address"/>

        <!--数组-->
        <property name="books">
            <array>
                <value>红楼梦</value>
                <value>西游记</value>
                <value>水浒传</value>
                <value>三国演义</value>
            </array>
        </property>

        <!--List-->
        <property name="hobbys">
            <list>
                <value>听歌</value>
                <value>敲代码</value>
                <value>看电影</value>
            </list>
        </property>

        <!--Map-->
        <property name="card">
            <map>
                <entry key="身份证" value="111111222222223333"/>
                <entry key="银行卡" value="1321231312312313123"/>
            </map>
        </property>

        <!--Set-->
        <property name="games">
            <set>
                <value>LOL</value>
                <value>COC</value>
                <value>BOB</value>
            </set>
        </property>

        <!--null-->
        <property name="wife">
            <null/>
        </property>

        <!--Properties-->
        <property name="info">
            <props>
                <prop key="driver">20190525</prop>
                <prop key="url"></prop>
                <prop key="username">root</prop>
                <prop key="password">123456</prop>
            </props>
        </property>
    </bean>
p c 命名空间
xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"    
    
<!--p命名空间注入,可以直接注入属性的值:property-->
<bean id="user" class="com.kuang.pojo.User" p:name="樊帅" p:age="18"/>


<!--c命名空间注入,通过构造器注入:construct-args-->
<bean id="user2" class="com.kuang.pojo.User" c:age="18" c:name="樊帅"  scope="prototype"/>		 

bean的作用域(scope)

singleton prototype request session application websocket

bean的自动装配
  • 自动装配是spring满足bean依赖的一种方式
  • spring会在上下文中自动寻找 并自动给bean装配属性

在spring中的三种装配方式

1 在xml中显示的配置

2在Java中显示的配置

3 隐式自动装配 bean

Autowired

byName自动装配 会自动在上下文中查找 和自己对象set方法后面的值对应的bean 只能识别名字叫樊帅

byType:会自动在上下文中查找 和自己对象属性类型相同的bean 狗类有两个实例byType不知道该调用哪个

注解方式实现自动装配

导入约束   context约束
配置注解的支持   这句话的意思为开启注解的支持<context:annotation-config/>

对bean进行注解方式

  • @Autowired 表明该类自动装配 该注解下的属性必须于bean实例下的id保持一致

    (也可以放在set方法上,有了这个注解就可以省略set方法)

  • @Autowired(require = false) 说明该对象可以为空 否则不允许为空

  • @Qualifier(value="") bean有多个id的情况下 指定装配的值

  • @Resourse (name = “”) 可以执行bean的id 不加name属性bean得唯一

@Autowired
private Dog dog;

bean实例下
<context:annotation-config/>
<bean id="dog" class="com.fan.pojo.Dog"/>

Resourse和autowirse的区别
 都是用来自动装配的 都可以放在属性字段上
 Autowirse默认使用bytype方式,如果多个类型相同,再通过byname(对象必须存在) Qualifier指定value
 resourse默认是通过byname的方式实现,如果找不到名字 则通过bytype实现  指定name
 执行顺序不同 Autowirse默认使用bytype方式  resourse默认是通过byname的方式实现

④注解实现

  • @Componment

    等价于<bean id="user" class="com.kuang.pojo.User"/>
    

    ​ @Value(“kuansghen”); 放在属性上 显性的给属性注入值 也可以注入在set方法上
    ​ public String name;

    相当于 <property name="name" value="kuangshen"/>
    

    衍生注解 这些都是Componment组件 仅仅是叫法不同 都是代表将类注册到spring容器中 装配bean 交给spring管理

    • dao @Repository
    • service @service
    • controller @ controller

    作用域 scope(“prototype”)

  • 小结

    • xml用来管理bean
    • 注解只负责完成属性的注入
    • 我们在使用的时候只需要注意开启注解的支持

扩展 使用Java的方式配置springboot javaconfig

在这里插入图片描述

aop

静态代理

类似于律师会务所 婚庆公司

角色分析

  • 抽象角色 一般会使用抽象类和抽象接口来解决
  • 真实角色 被代理的角色
  • 代理角色 代理真实角色 代理真实角色后 我们一般会做一些附属操作
  • 客户 访问代理对象的人

代码步骤

  • 接口 需要干什么service
  • 真实角色 ServiceImpl 真实角色和代理角色都实现了service
  • 代理角色 声明真实角色(将真实角色注入到代理角色) 代理角色一套流程,只需要将真实角色注入进去 降低了耦合
  • 客户端访问代理角色 调用接口方法实现

组合优于继承 一般不用继承 在类中定义一个私有的方法

在这里插入图片描述

在这里插入图片描述

动态代理

改变了静态代理的缺点

底层为反射

  • 动态代理和静态代理角色一样
  • 动态代理的代理类是动态生成的 不是我们直接写好的
  • 基于接口的动态代理(jdk的动态代理) 基于类的动态代理(chlib)
  • javaassist java字节码

需要连接两个类:Proxy invocationHandler(invoke方法)

动态代理的底层实现

动态代理具体步骤:

  1. 通过实现 InvocationHandler 接口创建自己的调用处理器;
  2. 通过为 Proxy 类指定 ClassLoader 对象和一组 interface 来创建动态代理类;
  3. 通过反射机制获得动态代理类的构造函数,其唯一参数类型是调用处理器接口类型;
  4. 通过构造函数创建动态代理类实例,构造时调用处理器对象作为参数被传入。
aop切面编程思路

一个项目的基本核心功能实现,能够跑起来后,需要增加一些辅助功能 横向开发

在这里插入图片描述

在这里插入图片描述

aop在spring中的作用

在这里插入图片描述

aop代码解释

applicationContext.xml

  • 方式一 使用原生Spring API接口
配置aop:需要导入aop的约束
<aop:config>
   <!--切入点:expression:表达式,execution(要执行的位置! * * * * *) 声明日志切面-->
   <aop:pointcut id="pointcut"
   expression="execution(* com.kuang.service.UserServiceImpl.*(..))"/>
   <!--执行环绕增加!-->
   <aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
   <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>
</aop:config>
  • 方式2 自定义类
声明业务对象
<bean id="diy" class="com.kuang.diy.DiyPointCut"/>
<aop:config>
   <!--自定义切面, ref 要引用的类 aop核心业务功能-->
   <aop:aspect ref="diy">
       <!--切入点-->
       <aop:pointcut id="point" 
       expression="execution(* com.kuang.service.UserServiceImpl.*(..))"/>
       <!--通知-->
       <aop:before method="before" pointcut-ref="point"/>
       <aop:after method="after" pointcut-ref="point"/>
   </aop:aspect>
</aop:config>
  • 方式3
<!--注册bean-->
<bean id="userService" class="com.kuang.service.UserServiceImpl"/>
<bean id="log" class="com.kuang.log.Log"/>
<bean id="afterLog" class="com.kuang.log.AfterLog"/>


<!--方式三-->
<bean id="annotationPointCut" class="com.kuang.diy.AnnotationPointCut"/>
<!--开启注解支持!   JDK(默认 proxy-target-class="false")   cglib(proxy-target-class="true")-->
<aop:aspectj-autoproxy/>

@Aspect 注解表示这是一个切面
   @Before("execution(* com.kuang.service.UserServiceImpl.*(..))")
   @After("execution(* com.kuang.service.UserServiceImpl.*(..))")     
   @Around("execution(* com.kuang.service.UserServiceImpl.*(..))")    环绕

执行顺序

环绕前
signature:void com.kuang.service.UserService.delete()
=====方法执行前======
删除了一个用户
环绕后
null
=====方法执行后======

spring整合mybatis

要和 Spring 一起使用 MyBatis,需要在 Spring 应用上下文中定义至少两样东西:一个
SqlSessionFactory 和至少一个数据映射器类。

可使用 SqlSessionFactoryBean 来创建 SqlSessionFactory 。

在spring的xml配置文件中配置工厂bean 就是下方的数据源配置

  • 1导入相关的包

    • junit
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
    
    • mybatis
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.47</version>
    </dependency>
    
    • mysql-connector-java
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.2</version>
    </dependency>
    
    • spring相关
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.1.9.RELEASE</version>
    </dependency>
    <!--Spring操作数据库的话,还需要一个spring-jdbc-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>5.1.9.RELEASE</version>
    </dependency>
    
    • aspectJ AOP 织入器
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.8.13</version>
    </dependency>
    
    • mybatis-spring整合包 【重点】
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis-spring</artifactId>
        <version>2.0.2</version>
    </dependency>
    
    lombok
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.16.10</version>
    </dependency>
    
    • maven静态资源过滤问题
    	<build>
            <resources>
                <resource>
                    <directory>src/main/java</directory>
                    <includes>
                        <include>**/*.xml</include>
                    </includes>
                    <filtering>true</filtering>
                </resource>
            </resources>
        </build>
    
  • 编写配置文件

  • 代码实现

配置文件

mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<!--configuration核心配置文件-->
<configuration>

    <typeAliases>
        <package name="com.kuang.pojo"/>
    </typeAliases>
    <!--设置-->
    <!--<settings>-->
        <!--<setting name="" value=""/>-->
    <!--</settings> -->
</configuration>

spring-dao.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"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd">

    <!--DataSource:使用Spring的数据源替换Mybatis的配置  c3p0  dbcp  druid
    我们这里使用Spring提供的JDBC : org.springframework.jdbc.datasource
    -->
    <bean id="dataSource" class=
    "org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/
        mybatis?useSSL=true&amp;useUnicode=true&amp;characterEncoding=UTF-8"/>
        <property name="username" value="root"/>
        <property name="password" value="123456"/>
    </bean>

    <!--sqlSessionFactory  关联mybatis-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <!--绑定Mabatis配置文件-->
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
        <property name="mapperLocations" value="classpath:com/kuang/mapper/*.xml"/>
    </bean>

    <!--SqlSessionTemplate:就是我们使用的sqlSession-->
    <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
        <!--只能使用构造器注入sqlSessionFactory,因为它没有set方法-->
        <constructor-arg index="0" ref="sqlSessionFactory"/>
    </bean>
</beans>

applicationContext.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"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd">

	//导入了spring的配置文件
    <import resource="spring-dao.xml"/>

    <!---->
    <bean id="userMapper" class="com.kuang.mapper.UserMapperImpl">
        <property name="sqlSession" ref="sqlSession"/>
    </bean>

    <bean id="userMapper2" class="com.kuang.mapper.UserMapperImpl2">
        <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
    </bean>
</beans>

事务管理

编程式事务管理

  • 将事务管理代码嵌到业务方法中来控制事务的提交和回滚

  • 缺点:必须在每个事务操作业务逻辑中包含额外的事务管理代码

声明式事务管理

  • 一般情况下比编程式事务好用。
  • 将事务管理代码从业务方法中分离出来,以声明的方式来实现事务管理。
  • 将事务管理作为横切关注点,通过aop方法模块化。Spring
xml的配置文件tx
xmlns:tx="http://www.springframework.org/schema/tx"

http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">

jdbc事务(配置声明式事务)

<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
	<property name="dataSource" ref="dataSource" />
</bean>

配置事务通知以及事务的传播性

<!--结合AOP实现事务的织入-->
<!--配置事务通知;-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!--给那些方法配置事务-->
<!--配置事务的传播特性:new  propagation= -->
    <tx:attributes>
        <tx:method name="add" propagation="REQUIRED"/>
        <tx:method name="delete" propagation="REQUIRED"/>
        <tx:method name="update" propagation="REQUIRED"/>
        <tx:method name="query" read-only="true"/>
        <tx:method name="*" propagation="REQUIRED"/>
    </tx:attributes>
</tx:advice>

<!--配置事务切入-->
<aop:config>
   <aop:pointcut id="txPointCut" expression="execution(* com.kuang.mapper.*.*(..))"/>
   <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
</aop:config>

事务的传播特性

事务传播行为就是多个事务方法相互调用时,事务如何在这些方法间传播。spring支持7种事务传播行
为:

  • propagation_requierd:如果当前没有事务,就新建一个事务,如果已存在一个事务中,加入到这
    个事务中,这是最常见的选择。

  • propagation_supports:支持当前事务,如果没有当前事务,就以非事务方法执行。

  • propagation_mandatory:使用当前事务,如果没有当前事务,就抛出异常。

  • propagation_required_new:新建事务,如果当前存在事务,把当前事务挂起。

  • propagation_not_supported:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。

  • propagation_never:以非事务方式执行操作,如果当前事务存在则抛出异常。

  • propagation_nested:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与

    propagation_required类似的操作

    Spring 默认的事务传播行为是 PROPAGATION_REQUIRED,它适合于绝大多数的情况。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值