第五章spring框架基础

一.spring

概念:

Spring是由Rod Johnson开发的一个开源容器框架,提供了控制反转[IoC],依赖注入,面向切面[AOP],事务管理,框架整合等功能,用于简化企业级应用开发.
特点:
1.轻量级:
Spring提供了许多服务,但这些服务默认关闭.同时,完整的Spring框架可以以在1M多大小的jar文件发布.
2.控制反转:
应用本身不负责依赖对象(被调用对象)的创建及维护,由外部容器负责依赖对象的创建及维护.
3.面向切面:
在运行时,动态的将代码切入到类的指定方法或位置上.
4.容器:
Spring包含并管理应用对象的配置和生命周期,因此Spring称为容器.

下载Spring:
官网地址:http://www.springsource.org/download
下载地址:https://repo.spring.io/libs-release-local/org/springframework/spring/

JDK与版本:
Spring Framework3.x: JDK5+
Spring Framework4.x: JDK6+
Spring Framework5.x: JDK8+

开发步骤:

第1步: 添加jar包

    commons-logging-1.2.jar 
    spring-aop-5.1.2.RELEASE.jar
    spring-beans-5.1.2.RELEASE.jar
    spring-context-5.1.2.RELEASE.jar
    spring-core-5.1.2.RELEASE.jar
    spring-expression-5.1.2.RELEASE.jar

添加jjar包

第2步: 创建Java类

    创建1个实体类
    备注: 测试Spring框架控制实体类[创建实体类,提供实体类对象]

实体类

第3步: 创建Spring配置文件

配置文件名称[beans.xml,application.xml,spring.xml,spring-bean.xml等等]任意,位置不限[src下].

配置文件模板位置[参考pdf或html]
创建配置文件信息

第4步: 编写Spring配置文件

   <bean>用于将指定位置的Java类,交给Spring容器管理[控制反转(帮你创建对象),依赖注入(向你提供对象)等等]
   示例:
   <bean class="bean.User" id="myuser" />

编写配置文件信息

第5步: 测试程序

    public static void main(String[] args) {
        //读取配置文件
        ApplicationContext app=new ClassPathXmlApplicationContext("配置文件名.xml");
        //从Spring容器中获得1个对象
        Object object= (Object ) app.getBean("id匿名");//Object-->User
        user.setName("小白");
        System.out.println(user);
    }

测试程序实例

二 .控制反转

概念:

控制反转[Inversion of Control]指应用本身不负责依赖对象(被调用对象)的创建及维护,由外部容器负责依赖对象的创建及维护.

控制反转实现方式:

第1种: 构造方法
<bean id="Bean匿名" class="类全名" />
![对象的构造函数](https://img-blog.csdnimg.cn/20210607231802196.png)
第2种: 工厂类的静态方法
<!-- Bean匿名=工厂类.静态方法名() -->
<bean id="Bean匿名" class="工厂类全名" factory-method="静态方法名"/>
![工厂类的静态方法](https://img-blog.csdnimg.cn/20210607231848352.png)

创建工厂
工厂静态方法测试类

第3种: 工厂类的对象方法
<bean id="别名A" class="工厂类全名"/>
<bean id="别名" factory-bean="别名A"  factory-method="方法名"/>

在这里插入图片描述

第4种: 注解方式
	a.添加context命名空间和context约束文件的地址
	b.添加<context:component-scan base-package="包名">
	c.在相关类上添加注解:
	注解: @Controller[标注在Action类上],@Service[标注在业务类上],@Repository,@Component[无法分辨层级,比如实体]
	作用: 声明将当前类交给Spring容器管理.
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210607232838939.png)

添加注释
测试类

三.依赖注入

概念:

依赖注入[Dependency Injection]指在运行期,由外部容器动态地将依赖对象[要使用的对象]注入到组件中.
注意: 依赖注入的前提是控制反转,被注入对象和接受注入的对象都必须被Spring容器管理.

依赖注入实现方式

方式1: setter方式
Java类:
private 普通属性类型 属性名;
private 自定义类类型 属性名;
private 集合类型 属性名;
//提供setter和getter
配置文件:
<bean id="Bean对象匿名" class="类全名">
	<property name="属性名" value="值" />
	<property name="属性名" ref="Bean对象匿名" />
	<property name="属性名">
		<list>\<value>
		<set>\<value>
		<map>\<entry>
		<props>\<prop>
	</property>
</bean>

//使用setter方式示例代码
<bean class="bean.Car" id="car"/>
<bean id="di_setter" class="bean.DI_Setter">
    <!--1.setter方式-->
    <!--普通数据-->
    <property name="id" value="1"/>
    <property name="name" value="小蜜瓜"/>
    <property name="income" value="12000"/>
    <property name="sex" value="女"/>
    <property name="marry" value="true"/>
    <!--对象数据-->
    <property name="car" ref="car"/>
    <!--集合数据-->
    <property name="myList" >
        <list >
            <value>AAA</value>
            <value>BBB</value>
            <value>CCC</value>
        </list>
    </property>
    <property name="myMap">
        <map>
            <entry key="a" value="1"/>
            <entry key="b" value="2"/>
            <entry key="b" value="3"/>
        </map>
    </property>
    <property name="mySet">
        <set>
            <value>AAA</value>
            <value>BBB</value>
            <value>CCC</value>
        </set>
    </property>
</bean>
方式2: 构造函数
Java类:
private 普通属性类型 属性名;
private 自定义类类型 属性名;
private 集合类型 属性名;
//提供有参构造方法
配置文件:
<bean id="Bean对象匿名" class="类全名">
	<constructor-arg index="参数索引" value="值" />
	<constructor-arg index="参数索引" type="类全名" ref="Bean对象匿名" />
	<constructor-arg index="参数索引" >
		<list/set/map/props>[参考setter方式]
	</constructor-arg>
</bean>

//构造函数使用示例
 <bean class="bean.Car" id="car"/>
<bean id="di_setter" class="bean.DI_Setter">
    <!--1.构造函数方式-->
    <!--普通数据--> 
    <constructor-arg name="id" value="1"/>
    <constructor-arg name="name" value="小蜜瓜"/>
    <constructor-arg name="income" value="12000"/>
    <constructor-arg name="sex" value="女"/>
    <constructor-arg name="marry" value="true"/>
    <!--对象数据-->
    <constructor-arg name="car" ref="car"/>
    <!--list集合数据-->
    <constructor-arg name="myList" >
        <list >
            <value>AAA</value>
            <value>BBB</value>
            <value>CCC</value>
        </list>
    </constructor-arg>
    <!---map集合数据-->
    <constructor-arg name="myMap">
        <map>
            <entry key="a" value="1"/>
            <entry key="b" value="2"/>
            <entry key="b" value="3"/>
        </map>
    </constructor-arg>
     <!--set方法-->
    <constructor-arg name="mySet">
        <set>
            <value>AAA</value>
            <value>BBB</value>
            <value>CCC</value>
        </set>
    </constructor-arg>
</bean>
方式3: 注解方式

Java类与配置文件:
a.配置文件中context命名空间和context约束文件的地址
在这里插入图片描述

b.配置文件中添加<context:component-scan base-package=“包名” />
在这里插入图片描述

c.在Java类的属性或setter上添加注解: @Autowired或@Resource.
在这里插入图片描述

@Autowired:
格式: @Autowired [(required=true)]
说明:
1.编写在属性或setter上,表示将Spring容器中同类型的Bean对象赋给该属性
2.根据属性类型到Spring容器中寻找bean对象,然后注入依赖对象
3.required默认为true,即配置文件中必须有同类型的Bean对象,否则报错

@Resource:
格式: @Resource[(name=“Bean对象匿名”)]
说明:
1.编写在属性或setter上面,表示将Bean对象匿名对应的对象赋给该属性
2.name属性值为Bean对象匿名,表示将Bean对象匿名对应的对象赋给该属性
3.@Resource标注在setter上或不设置name属性,则name属性值默认为属性名
4.若未设置name属性,并且按照默认名称仍然找不到依赖对象时,@Resource将会按属性类型查找同类型的bean对象,然后注入到属性中.

方式4: P命名空间

Java类:
提供属性的setter和getter方法,无需其他操作.
在这里插入图片描述

配置文件:

第1步: 添加命名空间
xmlns:p=“http://www.springframework.org/schema/p”
在这里插入图片描述
第2步: 注册bean,并注入数据
<bean id=“bean匿名” class=“类全名” p:属性名/属性名-ref=“值/匿名” />
在这里插入图片描述

四.使用注解实现SpringAOP

面向切面编程:

面向切面编程[Aspect Oriented Programming,简称AOP]指在运行时,动态的将代码切入到类的指定方法或位置上的编程思想.

术语:
  • aspect(切面): 指横切性关注点的抽象即为切面,它与类相似,类是对物体特征的抽象.[通俗讲,切面是定义了额外功能的类].
  • joinpoint(连接点): 指被拦截的点,分为属性,方法,构造器.Spring只支持方法类型的连接点.[通俗讲,应用额外功能的地方称为连接点]
  • pointcut(切入点): 指对"连接点"进行拦截的定义.[通俗讲,控制"哪些地方"应用切面]
  • advice(通知): 指拦截到"连接点"之后所要做的事情.通知分为前置通知,后置通知,异常通知,最终通知,环绕通知.
  • target(目标对象): 指要使用切面的类.
  • weave(织入): 指将"切面"应用到"目标对象"并导致"代理对象"创建的过程称为织入.
  • introduction(引入): 在不修改类代码的前提下,Introduction可以在运行期为类动态地添加一些方法或Field.
通知类型:
前置通知: 在目标方法执行之前,执行前置通知
后置通知: 在目标方法执行之后,执行后置通知
异常通知: 在目标方法执行并抛出异常时,执行异常通知
最终通知: 在目标方法执行之后或抛出异常时,执行最终通知
环绕通知: 在前置通知和目标方法之前,以及最终通知之前执行环绕通知
AOP通知执行过程

在这里插入图片描述
在这里插入图片描述

实现AOP方式

Spring提供了多种方式实现AOP,常用:(JDK动态代理和CGLIB代理)

方式一JDK动态代理:

使用Proxy类创建代理对象,含有处理类必须实现InvocationHandler接口.目标类必须实现接口[不限制类型],JDK动态代理通过实现目标类实现的所有接口,实现动态代理功能

方式二CGLIB代理:

使用Enhancer类生成代理对象,含有处理类必须实现MethodInterceptor接口.CGLIB通过生成目标类的子类,并重写目标类非final的方法实现动态代理功能

代理方式选择:
1.默认情况下,目标对象[被拦截的对象]必须实现了接口,Spring才会使用JDK动态代理.否则,Spring自动使用CGLIB代理
2.当目标对象实现了接口,可以设置aop:aspectj-autoproxy的proxy-target-class为true,强制使用CGLIB代理

使用注解方式实现AOP开发步骤:
第1步: 添加jar包

Spring基本jar+AOP相关jar

第2步:编写切面类,设置切入点和通知
  • @Aspect: 编写在类声明上面,表示声明当前类为切面类
  • @Pointcut: 编写在方法上面,定义切入点要求,"方法名()"即为切入点名
    格式:@Pointcut(value = “execution(表达式)”)

表达式:
execution(返回值类型 目录.类名.方法名(参数类型,…) && args(参数名,参数名,…))
说明:
1.返回值类型为void或类型全名,可配合"!“使用.[!void表示有返回值]
2.任意返回值/任意类名/任意方法名,都可以用”“表示.
3.若包含指定目录的任意子目录,用”.“表示
4.参数类型为类全名.任意个数和类型用”…"表示
5.args()表示必须有指定个数的参数
示例:@Pointcut(value = "execution(
service.UserService.*(…))")

  • @Before :编写在方法上面,鄙视声明当前方法为前置通知
    格式: @Before(value=“切入点名”,argNames=“参名,…”)
  • @AfterReturning: 编写在方法上面,表示声明当前方法为后置通知
    格式: @AfterReturning(value=“切入点名”,return=“参数名[接收返回值]”)
  • @After: 编写在方法上面,表示声明当前方法为最终通知
    格式: @After(value=“切入点名”)
  • @AfterThrowing: 编写在方法上面,表示声明当前方法为例外通知
    格式: @AfterThrowing(value=“切入点名”,throwing=“参数名[接收异常对象]”)
  • @Around: 编写在方法上面,表示声明当前方法为环绕通知
    格式: @Around(value=“切入点名”)

说明:
public Object 环绕通知(ProceedingJoinPoint point){
Object rs=point.proceed();//继续执行下1个通知或调用目标方法
return rs; //必须返回,否则后置通知无法获得目标方法返回值
}

定义切面类 在切面类中切入点上说明拦截目标 实现动态添加
@Component
@Aspect    //声明当前类为切入类 切入类包含额外的方法
public class AOP {
    //定义一个切入点 
    @Pointcut(value = "execution(* service.UserService.*(..))")
    public void test(){
        System.out.println("定义切入点:切入点为被标注的方法的名称");
    }
    //定义前置通知[用来拦截方法的参数]
    @Before(value = "test() && args(p1) ",argNames = "p1")
    public  void qianzhitongzhi(Object p1){
        System.out.println("前置通知");
        System.out.println("拦截的方法参数"+p1);
    }

    //定义后置通知[用来拦截方法的返回值]
    @AfterReturning(value = "test()",returning = "returnDate")
    public void houzhitongzhi(Object returnDate){
        System.out.println("后置通知");
        System.out.println("被拦截的方法的返回值为"+returnDate);
    }

    @After("test()")
    public void zuizhongtongzhi(){
        System.out.println("最终通知");
    }

    //定义异常通知[用来拦截异常和打印异常信息]
    @AfterThrowing(value = "test()",throwing = "e")
    public void  yichangtongzhi(Exception e){
        System.out.println("异常通知");
        System.out.println(e.getMessage());

    }

    //环绕通知
    @Around("test()")
    public  Object huanraotongzhi(ProceedingJoinPoint point ) throws Throwable {
        System.out.println("进入环绕通知");
        Object ob = point.proceed();
        System.out.println("离开环绕通知");
        return  ob;
    }
}

注意: @Before,@AfterReturning,@After,@AfterThrowing,@Aroud默认属性为value[切入点名]

第3步: 开启aspectj自动代理,并注册切面类
<context:component-scan base-package="bean,service,aop"/<!--开启自动扫描并将有注释的类自动注册-->
<aop:aspectj-autoproxy/><!--启动AspectJ自动代理功能-->

在这里插入图片描述

第4步: 注册AOP
    <!--注册切面类-->
    <bean id="myaop" class="aop.MyAOP" />
    或
    @Component <!--若使用注释即可自动注册该类-->
第5步: 正常编写程序,测试AOP效果

在这里插入图片描述

使用XML方式实现AOP

步骤:

第1步: 添加jar包

同annotation方式

第2步: 编写切面类

同annotation方式,但是移除所有的注解[在配置文件中实现注解的功能].

/*@Component*/
@Aspect    /*声明当前类为切入类 切入类包含额外的方法*/
public class AOP1 {

    @Pointcut(value = "execution(* service.UserService.*(..))")
    public void test(){
        System.out.println("定义切入点:切入点为被标注的方法的名称");
    }
    
    @Before("test()")
    public  void qianzhitongzhi(){
        System.out.println("前置通知");
    }

    @AfterReturning("test()")
    public void houzhitongzhi(){
        System.out.println("后置通知");
    }

    @After("test()")
    public void zuizhongtongzhi(){
        System.out.println("最终通知");
    }


    @AfterThrowing("test()")
    public void  yichangtongzhi(){
        System.out.println("异常通知");
    }

    //环绕通知-
    @Around("test()")
    public  Object huanraotongzhi(ProceedingJoinPoint point ) throws Throwable {
        System.out.println("进入环绕通知");
        Object ob = point.proceed();
        System.out.println("离开环绕通知");
        return  ob;
    }
}
第3步: 编写Spring配置文件

a.将切面类交给Spring管理
b.配置面向切面

<!--开启自动扫描-->
<context:component-scan base-package="bean,service,aop"/>
<aop:config>
	<!--定义1个切面类-->
	<aop:aspect id="myaop" ref="myAOP">
		<!--定义1个切入点拦截service.UserService类中的所有方法(有参无参)-->
		<aop:pointcut id="mycut" expression="execution(* service.UserService.*(..))"/>
		<!--定义通知-->
		<aop:before method="beforeDeal" pointcut-ref="mycut" arg-names="joinPoint" />
		<aop:after-returning method="afterReturningDeal" pointcut-ref="mycut" returning="returnData"/>
		<aop:after method="afterDeal" pointcut-ref="mycut" />
		<aop:after-throwing method="afterThrowingDeal" pointcut-ref="mycut" throwing="e"/>
		<aop:around method="aroundDeal" pointcut-ref="mycut" />
	</aop:aspect>
</aop:config>
第4步: 编写程序,测试

同annotation方式

mybatis与spring框架整合

框架的作用:

MyBatis: 用于替代JDBC,用于数据持久化
Spring: 用于整合框架,提供整合功能及其他功能[IoC,DI,AOP,事务管理等等]
SpringMVC: 用于替代JSP,用于处理请求和响应[SpringMVC属于Spring的一部分]

Spring整合MyBatis:

MyBatis功能/操作: 配置文件[实体类别名,数据源,映射文件等等],映射文件[业务标签],MyBatis代码[SqlSessionFactory,SqlSession等对象操作]
Spring功能/操作: IoC,DI,AOP,事务管理

整合目标:

  • 用Spring来替代MyBatis中的数据源,提供SqlSessionFactory,SqlSession等对象,管理事务
  • .MyBatis整合中要做的内容: 配置文件[保留 实体类别名,映射文件等等],映射文件[业务标签]无变化,MyBatis代码[业务代码]

整合步骤:

第1步: 整合jar包
  1. MyBatis相关jar包:
    mybatis-3.5.1.jar
    log4j-1.2.17.jar
  2. 数据库驱动器:
    mysql-connector-java-5.1.22-bin.jar
  3. Spring相关jar:
    commons-logging-1.2.jar
    spring-aop-5.1.2.RELEASE.jar
    spring-beans-5.1.2.RELEASE.jar
    spring-context-5.1.2.RELEASE.jar
    spring-core-5.1.2.RELEASE.jar
    spring-expression-5.1.2.RELEASE.jar
  4. spring-jdbc-5.1.2.RELEASE.jar
    spring-tx-5.1.2.RELEASE.jar
  5. aopalliance-.jar
    aspectjrt.jar
    aspectjweaver.jar
    cglib-nodep-2.1_3.jar
  6. 额外jar:
    连接池: commons-dbcp-1.4.jar,commons-pool-1.6.jar
    MyBatis与Spring整合: mybatis-spring-2.0.3.jar
第2步: 整合配置文件

MyBatis配置文件:
mybatis-conf.xml[实体类别名,环境(数据源),加载映射],
log4j.xml[控制日志输出],映射文件[业务标签]
Spring配置文件: application.xml[控制反转]

整合后:
MyBatis配置文件中: 去掉环境配置(数据源),实体类别名,加载映射
整合后mybatis-config.xml文件中的内容

log4j.xml[控制日志输出]: 无需操作
映射文件[业务标签]: 无需操作、
Spring配置文件中: 添加数据源,提供SqlSessionFactory,提供事务管理
1.开启自动扫描: 扫描service,action,mapper等等,实现控制反转[管理相关对象]---->注解方式实现控制反转
2.提供数据源
3.提供SqlSessionFactoryBean
4.提供事务管理 @@Transactional标注的类中所有关于数据库操作时,自动提交事务,以及回滚事务
5.注册其他必须的对象
Spring配置文件中的内容

第3步: 整合代码

MyBatis代码正常编写即可,若需要SqlSessionFactory对象可以从Spring容器中获得.

Mapper方式实现CURD:
1.Mapper接口: 正常编写
2.业务类: 声明Mapper接口类型的属性,并由Spring注入属性值
3.注册Mapper接口:

 方式1: 指定加载某个1Mapper接口
      <bean class="org.mybatis.spring.mapper.MapperFactoryBean" id="mapperFactoryBean">
      <property name="sqlSessionFactory" ref="factory" />
      <property name="mapperInterface" value="mapper.UserMapper" />
      </bean>
    方式2: 指定加载某个包中的所有Mapper接口
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer" id="mapperScannerConfigurer" >
    <property name="sqlSessionFactoryBeanName" value="factory" />
    <property name="basePackage" value="mapper" />
    </bean>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值