最简洁 学完Spring框架

Spring框架

- 怎么学框架

  1. 知道框架能做什么
  2. 框架的语法
  3. 会用后 以后在考虑内部实现
  4. 通过以上步骤 可以自己实现一个框架

一、概述

1. 框架是什么

  • Spring 是一个容器 管理对象,属性赋值,底层使用反射机制

  • 主要是解决企业开发难度

  • 模块之间,类之间的管理解耦合 解决对象之间的关系

  • 核心技术 ioc aop

2. 优点

  • 轻量

  • 针对接口编程 解耦合

  • 支持AOP 面向切面编程

  • 方便集成其他框架 像插座

    3. Spring体系结构

    数据访问 Web AOP 集成 容器 测试

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-34D4uJcE-1631101190405)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210904113452824.png)]

二、 IOC控制反转

1. 为什么使用IOC:

目的减少代码的改动,也能实现不同功能 解耦合

2. IOC(控制反转)是一个思想。

  • 控制:对象的创建,赋值,对象关系之间的管理

  • 反转:把开发人员new对象的权利 转移给容器实现

  • 正转:开发人员使用代码中 new对象

  • 容器:是一个服务器软件,一个框架(Spring)

3. IOC的技术实现:

DI实现IOC的功能

DI:依赖注入 只需提供对象的名称 对象创建、赋值等 由容器内部实现

三、 入门案例

1. 加入依赖

<!--//Spring依赖-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.2.5.RELEASE</version>
</dependency>

2.创建类(接口和实现类)

service包下创建接口 imp包下实现类

3. 创建Spring配置文件

<!--在资源目录下 要创建Spring的xml-->
<?xml version="1.0" encoding="UTF-8"?>
<!--beans:根标签 spring把java对象成bean-->
<!--spring-beans.xsd:格式约束文件-->
<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">
<!--    声明bean 告诉spring创建对象 
    id:自定义名 spring通过这个名找到对象
    class:全限定名称(不能是接口 必须类)-->
    <bean id="some" class="com.baidu.service.imp.SomeServiceImp"/>
</beans>

4. 测试使用对象

//ApplicationContext:是Spring的容器 通过容器获取对象
//ClassPathXmlApplicationContext:类路径加载Spring配置文件
ApplicationContext app = 
new ClassPathXmlApplicationContext("beans.xml");

//getBean方法:获取
xxxx xx = 
(xxxx)app.getBean("配置文件中的bean的id");

5. 注意点:

spirng: 创建对象的时间:创建spring的容器时,创建beans的所有对象

spring: 默认调用无参构造

获取容器中对象的信息api:

getBeanDefinitionCount(): 获取定义的对象数量

getBeanDefinitionNames():获取所有定义对象的名称

四、 DI实现语法

1. 通过spring完成 属性赋值

基本类型和String在这属于简单类型

引用

xml和注解注入区别:

经常需要修改的 xml否则 注解

xml 代码和值 完全分开

​ 但是代码比较多 不够直观

注解 快 方便 可读好

​ 但是在代码内 修改比较麻烦

1.1 基于XML的DI实现

spring 配置文件中,使用标签和属性

set注入

spring 调用类的set方法 必须有

//在spring配置文件bean中为属性赋值
//实际调用set方法
<property name="属性名" value="值 都要加引号"/>

//引用类型
<property name="属性名" ref="time"/>
<bean id="time" class="java.util.Date"/>
构造注入

调用类的有参构造方法

<constructor-arg 
    name="构造方法的新参名"
    index="从0开始 构造方法参数位置"
    ref="引用"
    value="简单类型值"/> 
//还有个省略index 但是要按方法参数位置
1.2 基于注解的DI实现
实现步骤
  1. 加依赖

  2. 创建类 加注解

  3. 创建spring配置文件 声明组件扫描器

    //输入com 就会出来
    <context:component-scan base-
    package="包名"/>
    //指定包 三种方式
    //一个一个 
    //   分号;间隔 
    //        指定父包
    
注解
@Component 创建对象
  • 类上使用

  • 创建对象 value(可省略)= bean.id

  • 不提供名称 默认首字符小写类名

@Respotory
  • 持久层 dao
@Service
  • 业务层 service
@Controller
  • 控制器类

以上三种 跟Component一样创造对象 但是有额外含义

项目对象 分层的

@Value 简单赋值
  • set或属性上使用 value = “值”
@Autowired 引用赋值
  • 属性或set上

  • 按类型自动注入

  • //按名自动注入
    @Autowired
    @Qualifier("对象名")
    //如果对象名错了 required = true 赋值无 null
    //如果对象名错了 required = false 报错
    @Autowired(required = false)
    @Qualifier("对象名")
    
@Resource
  • 是JDK中的自动注入注解 需要加入依赖
  • 自动先用byName再用byType
  • 如果要知道注入方式 加 name属性= “方式”
set注入

spring 调用类的set方法 必须有

构造注入

调用类的有参构造方法

1.3 引用类型自动注入
byName(按名注入):
//类的属性名和spring配置文件bean id名一致 类型一致
<bean id=""class="" autowire="byName">
    //简单类型赋值 引用自动
</bean>
byType(按类型注入):
//spring配置文件bean class类型一致或父子接口类关系
//唯一bean
<bean id=""class="" autowire="byType">
    //简单类型赋值 引用自动
</bean>

1.4 多个配置

1.优点
  • 文件小 效率高
  • 避免多人使用冲突
  1. 按功能模块

  2. 按类的功能

2.使用
//创建一个Srping主配置文件total.xml//里面包含其他配置文件spring-*.xml//一般不定义对象<import resoutce = "classpath:路径.xml">    //可以使用通配符*//不能包含total.xml//需要在目录下才能使用<import resoutce = "classpath:spring-*.xml">
使用属性配置文件 注入
//主配置文件//${xxx}<context:property-placeholder location="classpath:xxx.properties"/>

五、 AOP (面向切面编程)

1. 动态代理

CGLIB代理 继承 类、方法不能final

JDK动态代理 必须实现接口

实现步骤:

1.创建目标类

2.创建InvocationHandler接口实现类

public class MyHandler implements InvocationHandler {
	//目标对象
    Object target = null;

    public MyHandler(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    	//返回对象
        Object res = null;
        //方法执行前
        MyTools.doTime();
        //目标对象,方法集
        ob = method.invoke(target,args);
        //方法执行后
        MyTools.doTrans();
        return res;
    }
}

3.实现目标类增加功能

4.使用jdk中Proxy 创建代理对象

接口 my = new 实现类();
        InvocationHandler handler = new MyIncationHandler(my);
        My proxy = (My) Proxy.newProxyInstance(my.getClass().getClassLoader(),
                my.getClass().getInterfaces(),
                handler);
	proxy.xxx();

2. 作用

  • 在代码不变的情况下 增加方法里面的功能
  • 减少代码重复
  • 解耦合
  • 专注业务

总结:就是动态代理的规范化,让开发人员用统一的方法 使用动态代理

3. 理解面向切面编程

  • A:切面 给方法增加的功能 非业务功能方法
  • O:面向 对着
  • P:编程
  • 连接点 业务方法
  • 切入点 连接点的集合

1)分析项目功能 找出切面

2)合理安排切面时间

3)合理安排切面位置 哪个类 哪个方法增

1.切面干什么 2. 执行位置 3. 执行时间

spring在内部实现了aop 但是比较繁琐 很少使用

4.aspectJ框架 专门做AOP

优秀的面向切面框架 通过spring就能使用它

1. 使用xml配置文件:配置全局事务
2. 使用注解 aspectJ有5个注解
  • 切面的执行时间 在规范中叫做 通知
@Before 前置通知
  • 方法上面 属性 value:切入点表达式
@AfterReturning 后置通知
  • 方法是有参数的 建议Object 自定义名

  • 属性value:切入点表达式

  • returning:自定义变量 Object 自定义名 跟方法参数名一样

  • 获取方法返回值 可以修改返回值

@Around 环绕通知
  • 必须有返回值 建议Object

  • 固定参数ProceedingJoinPoint pjp

  • 功能最强 方法前后都行

  • 控制目标方法是否被执行

  • 修改目标方法的执行结果 影响最后的调用结果

  • 等同JDK invoke

  • 最多 执行事务

    @Around("execution(String doSome(..))")public Object doTime(ProceedingJoinPoint pjp) throws Throwable {    Object result = null;    System.out.println("hhh");    result = pjp.proceed();    return result;}
    
@AfterThrowing 了解 异常通知
  • 属性throwing
  • 方法参数 Exception 自定义名 要跟上面属性一致
@After 了解 最终通知
  • 总是会被执行 类似finally
Pointcut辅助 定义切入点别名
@Pointcut"execution(String doSome(..))"private void 别名(){}@Around(value = "别名()")
3. Aspectj切入点表达式

execution

(访问类型? 返回类型 包类名?方法名(形参类型) 抛出异常?)

*:0-多个字符

…:方法参数中 多个参数

​ 包名后 当前包及子包

+:类名后 当前类 子类

​ 接口后 当前接口实现类

4. 使用步骤

1.加spring aspectJ依赖

<!--//Spring依赖-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.2.5.RELEASE</version>
</dependency>
<!--//aspectJ依赖-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>5.2.5.RELEASE</version>
</dependency>

2.目标类:接口和它的实现类

给类中的方法增加功能

3.创建切面类:普通类

在上面加@Aspectj:作用当前类是切面类

切面内定义方法 public void 自定义(不是自定义)

//JoinPoint参数 需要方法的信息
//必须是参数的第一个
public void doTime(JoinPoint jp){
    //方法数字签名
    System.out.println(jp.getSignature());   
//方法名 
    System.out.println
    (jp.getSignature().getName());
    //方法参数
    Object[] obj = jp.getArgs();
    for(Object o:obj){
        System.out.println(o);
    }
    System.out.println(new Date());
}

4.创建spring的配置文件

//创建目标类和切面类对象 bean
<aop:aspectj-autoproxy/>
    
//想用CGLIB代理 继承的方式 接口也能
<aop:aspectj-autoproxy proxy-target-class=true/>

六、集成mybatis spring框架

使用技术 aoc

1.加依赖

<!--Spring依赖-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.2.5.RELEASE</version>
</dependency>
<!--Spring事务-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-tx</artifactId>
    <version>5.2.5.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>5.2.5.RELEASE</version>
</dependency>

<!--mybatis依赖-->
<dependency>
  <groupId>org.mybatis</groupId>
  <artifactId>mybatis</artifactId>
  <version>3.5.7</version>
</dependency>
<!--mysql驱动-->
<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <version>5.1.23</version>
</dependency>
<!--mybatis和Spring-->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>1.3.1</version>
</dependency>
<!--阿里公司的数据库连接池-->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.12</version>
</dependency>
    
<!-- pom.xml下的build中加入 -->
<resources>
 	<resource>
        <directory>src/main/java</directory>
        <includes>
          	<include>**/*.properties</include>
          	<include>**/*.xml</include>
        </includes>
        <filtering>false</filtering>
	</resource>
</resources>   

2.创建实体类 Dao接口 sql映射文件

3.主配置文件mybatis

4.service 业务接口和实现类

5.创建spring配置文件

<?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">

    <context:property-placeholder location="classpath:jdbc.properties"/>
    <!--声明数据源DataSource-->
    <bean id="myDataSource" class="com.alibaba.druid.pool.DruidDataSource"
          init-method="init" destroy-method="close">
        <!--set注入数据库信息    -->
        <property name="url" value="${mysql.url}"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
        <property name="maxActive" value="20"/>
    </bean>
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!--set注入将数据库连接池交给dataSource属性-->
        <property name="dataSource" ref="myDataSource"/>
        <!--mybatis主配置文件的位置
            configLocation属性是Resource类型 读取配置文件
            value属性指定文件路径需要 classpath:
        -->
        <property name="configLocation" value="classpath:mybatis.xml"/>
    </bean>
    <!--创建dao对象 使用是sqlSession对象的getMapper方法(xxx.class)
        生成每个dao接口的代理对象
    -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!--指定SqlSessionFactory对象的id-->
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
        <!--指定包名 dao接口所在的包名-->
        <property name="basePackage" value="com.baidu.dao"/>
    </bean>
    <!--声明service对象-->
    <bean id="studentService" class="com.baidu.services.impl.StudentServiceImpl">
        <property name="studentDao" ref="studentDao"/>
    </bean>
</beans>

6.测试

ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
StudentService studentService = (StudentService) app.getBean("studentService");
List<Student> students = studentService.sel();

//事务是自动提交的

7.资源配置文件

//spring配置文件中
<context:property-placeholder location="classpath:jdbc.properties"/>

七、spring事务

  • 什么是事务?
    • 一组sql语句的集合 我们希望多个sql语句能都成功或都失败
  • 不同数据库有多个种处理方法
    • spring提供一种统一模型 完成不同数据库的事务的处理方式
  • 总结:
    • spring的事务是统一模型
      1. 指定使用的事务管理器对象
      2. 指定类,那些方法加入事务的功能
      3. 指定事务隔离级别 传播方式 超时

接口PlatformTransactionManager 定义了commit rollback

实现类 mybatis DataSourceTransactionManager

1. 适合 中小型项目使用注解

<!--spring配置文件 声明事务管理器对象-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="myDataSource"/>
    </bean>
    <!--开启事务注解驱动 告诉spring 我要使用注解 管理事务-->
    <!--赋值数据库信息-->
    <tx:annotation-driven transaction-manager="transactionManager"/>
//在方法上加入@Transactional 默认就好 只能是public

2.适合大型项目 使用aspectj框架

  • 很多类、方法配置事务

  • 在spring配置文件中声明类、方法需要的事务

  • 业务方法和事务配置完全分离

使用步骤
1.加入aspectj框架依赖
    <!--//aspectJ依赖-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aspects</artifactId>
      <version>5.2.5.RELEASE</version>
    </dependency>
2.声明事务管理器对象
<!--spring配置文件 声明事务管理器对象-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="myDataSource"/>
    </bean>
        
    <tx:advice id="transactionInterceptor" transaction-manager="transactionManager">
        <tx:attributes>
            <!--完整的方法名 不带包和类 可以加通配符*-->
            <!--属性propagation:传播方式
            	isolation:隔离级别
            	rollback-for:指定的异常类 发生异常一定回滚
            -->
            <tx:method name="buy"/>
        </tx:attributes>
    </tx:advice>
     
    <!--配置aop*-->
    <aop:config>
        <!--配置切入点:指定包中那些类 使用事务
        	id:切入点表达式的自定义名
        	返回值 包名..方法-->
        <aop:pointcut id="servicePt" expression="execution(* *..services..*.*(..))"/>
            <!--关联advice和pointcut的id-->
        <aop:advisor advice-ref="transactionInterceptor" pointcut-ref="servicePt"/>
    </aop:config>

P97-102

web复习一下再看

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值