Spring-Study

Posted 轻舟一曲

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring-Study相关的知识,希望对你有一定的参考价值。

[我的工作台 - Gitee.com]:

常用依赖

pom.xml

    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.3.3</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/junit/junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.1</version>
            <scope>test</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
        <dependency>
           <groupId>org.aspectj</groupId>
           <artifactId>aspectjweaver</artifactId>
           <version>1.9.4</version>
        </dependency>

    </dependencies>

beans.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:context="http://www.springframework.org/schema/context"
       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/context
        https://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd
       ">
<!--开启注解的支持-->
       <context:annotation-config/>

</beans>

spring-dao.xml


dataSource和sqlSession的Spring方式注入


        <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=false&amp;useUnicode=true&amp;
                                            characterEncoding=UTF-    8&amp;allowPublicKeyRetrieval=true"/>
                <property name="username" value="root"/>
                <property name="password" value="8613919"/>
        </bean>
        <!--    sqlSessionFactory-->
        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
                <property name="dataSource" ref="dataSource" />
<!--            绑定mybatis配置文件-->
                <property name="configLocation" value="classpath:mybatis-config.xml"/>
                <property name="mapperLocations" value="classpath*:com/mf/dao/**/*.xml"/>
        </bean>
<!--        SqlSessionTemplate就是我们使用的sqlSession-->
        <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<!--             只能使用构造器注入sqlSessionFactory,因为他没有set方法-->
                <constructor-arg index="0" ref="sqlSessionFactory"/>
        </bean>

目录

Spring

简介

spring理念:使现有技术更加实用,本身就是一个大杂烩,整合现有的框架技术。

一句话概括:spring是一个轻量级的控制反转Ioc和面向切面AOP的容器(框架)。

优点

  • 轻量级,非入侵;
  • 控制反转,面向切面;
  • 支持事务处理,对象框架整合。

拓展

IOC理论推导

spring7层分层架构:

**核心容器:**通过beanfactory使用控制反转定义创建、配置、管理bean的方式。

spring上下文:配置文件,提供一些企业服务。

**springAOP:**将声明性事务切入应用程序。

**springDAO:**面向 JDBC 的异常,降低了需要编写的异常代码数量(例如打开和关闭连接)。

Spring ORM:若干个 ORM 框架。

Spring Web 模块:为基于 Web 的应用程序提供了上下文

Spring MVC 框架:MVC 框架是一个全功能的构建 Web 应用程序的 MVC 实现。

1.ApplicationContext.xml读取配置文件

2.POJO根据元数据创建和组装Bean

3.程序使用时再从Ioc容器中取出需要的对象

Ioc实现方式有两种:xml配置和注解

采用xml配置,bean的定义信息和实现分离;

注解把二者合二为一,定义信息直接以注解形式在实现类中,从而达到零配置。

IOC的本质

控制反转的本质是一种设计思想,DI(依赖注入)是实现IOC的一种方式。

  • UserDao接口
  • UserDaoImpl实现类
  • UserService业务接口
  • UserServiceImpl业务实现

HelloSpring

1.创建实体,创建接口和实现类

2.注册beans.xml,交由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"
      xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">

   <!--bean就是java对象 , 由Spring创建和管理-->
   <bean id="hello" class="com.kuang.pojo.Hello">
       <property name="name" value="Spring"/>
   </bean>
    
   <bean id="MysqlImpl" class="com.kuang.dao.impl.UserDaoMySqlImpl"/>
   <bean id="OracleImpl" class="com.kuang.dao.impl.UserDaoOracleImpl"/>

   <bean id="ServiceImpl" class="com.kuang.service.impl.UserServiceImpl">
       <!--注意: 这里的name并不是属性 , 而是set方法后面的那部分 , 首字母小写-->
       <!--引用另外一个bean , 不是用value 而是用 ref-->
       <property name="userDao" ref="OracleImpl"/>
   </bean>

</beans>

3.要用直接ApplicationContext 从beans.xml拿到(再也不用new 对象了)

IOC创建对象的方式

1.通过无参构造方法来创建。

2.通过有参构造方法(还是用Set方法)来创建。

beans.xml参数设置3种方式:

1.根据index参数下标。

2.根据参数名字。推荐使用

3.根据参数类型。不建议使用

<constructor-arg index="0" value="kuangshen2"/>

<property name="name" value="马富说"/>

<constructor-arg type="java.lang.String" value="kuangshen2"/>

配置文件加载的时候,其中管理的对象已经创建和初始化了。

传统对象由程序本身控制创建。

spring由IOC容器创建对象并设置属性,程序本身不创建对象而是被动接受对象,利用set方法进行注入,这个过程就叫做控制反转。

Spring配置

别名alias

Bean配置

id是bean的标识符,要唯一;

没有配置id,name就是默认标识符;

有id又有name,name就是别名;

两个都没有,applicationContext.getBean(.class)获取对象。

<bean id="hello" name="hello2 h2,h3;h4" class="com.kuang.pojo.Hello">
   <property name="name" value="Spring"/>
</bean>

import

依赖注入

依赖IOC容器创建对象,注入对象属性值。

构造器注入

Set方式注入【重点】

拓展方式注入

1.常量注入

2.bean注入 ref

3.数组注入 array

4.list注入 list

5.Map注入 map entry

6.set注入 set

7.null注入

8.properties注入 props prop

p标签注入(set方式注入)

c标签注入(有参构造方式注入)

bean的作用域

单例 singleton

原生型 score=prototype

request创建自己的bean

session共享bean

Bean自动装配

spring装配bean方式有三种:

1.java中显示配置

2.xml中显示配置

3.隐式bean发现机制和自动装配(组件扫描component scanning,自动装配autowiring)

什么叫自动装配:spring自动发现应用上下文所创建的bean,spring自动满足bean之间的依赖。

自动装配有3种方式:

byname

bytype

注解(推荐使用)

xml以前的bean装配方式

ByName自动装配,ByType自动装配

   <!--原来的方式-->
   <bean id="dog" class="com.kuang.pojo.Dog"/>
   <bean id="cat" class="com.kuang.pojo.Cat"/>

   <bean id="user" class="com.kuang.pojo.User">
       <property name="cat" ref="cat"/>
       <property name="dog" ref="dog"/>
       <property name="str" value="qinjiang"/>
   </bean>

   <!--byname自动装配-->
    <bean id="user" class="com.kuang.pojo.User" autowire="byName">
       <property name="str" value="qinjiang"/>
    </bean>

    <!--bytype自动装配,类型要唯一-->
    <bean id="dog" class="com.kuang.pojo.Dog"/>
    <bean id="cat" class="com.kuang.pojo.Cat"/>
    <!--类型不唯一报错-->
    <bean id="cat2" class="com.kuang.pojo.Cat"/>

    <bean id="user" class="com.kuang.pojo.User" autowire="byType">
       <property name="str" value="qinjiang"/>
    </bean>

使用注解实现自动装配(推荐使用)

导使用注解就需要导入spring-aop的包

开启注解支持

<context:annotation-config/>

@Autowired是按类型自动装配的,不支持id匹配

//如果允许对象为null,设置required = false,默认为true
@Autowired(required = false)
private Cat cat;
@Autowired
private Dog dog;
private String str;
<context:annotation-config/>

<bean id="dog" class="com.kuang.pojo.Dog"/>
<bean id="cat" class="com.kuang.pojo.Cat"/>
<bean id="user" class="com.kuang.pojo.User"/>

@Autowired加上 @Qualifier可以根据byname自动装配,就可以支持id匹配了

@Autowired
@Qualifier(value = "cat2")
private Cat cat;
@Autowired
@Qualifier(value = "dog2")
private Dog dog;

@Resource

如有指定的name属性,先按该属性进行byName方式查找装配;

其次再进行默认的byName方式进行装配;

其次再按byType的方式自动装配。

@Resource
private Cat cat;
@Resource
private Dog og;

基于注解开发spring

导入注解支持包aop 和 context约束

扫描包 和 添加注解驱动

<context:component-scan base-package="com.kuang.pojo"/>
<context:annotation-config/>  

包下的类增加注解@Component,属性注入 @Value(如果提供了set方法,在set方法上添加@value(“值”)

@Component("user")
// 相当于配置文件中 <bean id="user" class="当前注解的类"/>
public class User 
   @Value("秦疆")
   // 相当于配置文件中 <property name="name" value="秦疆"/>
   public String name;

不同层的衍生注解:本质都是@component

  • @controller :web层
  • @service:service层
  • @repository:dao层

bean的自动装配上节已讲。

小结:

xml与注解比较:

  • xml适用任何场景,结构清晰,维护方便

  • 注解不是自己提供的类适用不了,开发方便

**推荐使用xml和注解整合开发:**xml管理bean,注解完成属性注入

基于Java类开发spring

编写实体类

创建config配置包,编写配置类

@Configuration  //代表这是一个配置类
public class MyConfig 

   @Bean //通过方法注册一个bean,这里的返回值就Bean的类型,方法名就是bean的id!
   public Dog dog()
       return new Dog();
  


@Test
public void test2()
   ApplicationContext applicationContext =
           new AnnotationConfigApplicationContext(MyConfig.class);
   Dog dog = (Dog) applicationContext.getBean("dog");
   System.out.println(dog.name);

@Import(MyConfig2.class) //导入合并其他配置类,类似于配置文件中的 inculde 标签

代理模式

静态代理

1.抽象角色

2.具体角色

3.代理角色

4客户

缺点:增加具体角色要增加代理类,工作量变大,改动功能需要改动代码量大,违反开闭原则。

动态代理

动态代理分两类:基于接口(JDK动态代理)和基于类(cglib) 。

现在比较多使用javasist生成动态代理。

基于JDK动态代理

两个核心类

InvocationHandler:调用处理程序

Proxy :实现了接口InvocationHandler

Proxy提供了创建动态代理类和实例的静态方法,它也是由这些方法创建的所有动态代理类的超类。

两个重要方法:

getProxy() : newProxyInstance(loader,interfaces,h);

loader-类加载器来定义代理类

interfaces-代理类实现接口列表

h-调度方法调用的调用处理函数

invoke() : 处理代理实例上的方法调用并返回结果

//生成代理类
public Object getProxy()
   return Proxy.newProxyInstance(this.getClass().getClassLoader(),
                                 rent.getClass().getInterfaces(),this);

public class ProxyInvocationHandler implements InvocationHandler 
   private Rent rent;

   public void setRent(Rent rent) 
       this.rent = rent;
  

   //生成代理类,重点是第二个参数,获取要代理的抽象角色!之前都是一个角色,现在可以代理一类角色
   public Object getProxy()
       return Proxy.newProxyInstance(this.getClass().getClassLoader(),
               rent.getClass().getInterfaces(),this);
  

   // proxy : 代理类 
   //method : 代理类的调用处理程序的方法对象.
   // 处理代理实例上的方法调用并返回结果
   @Override
   public Object invoke(Object proxy, Method method, Object[] args) throws Throwable 
       seeHouse();
       //核心:本质利用反射实现!
       Object result = method.invoke(rent, args);
       fare();
       return result;
  

   //看房
   public void seeHouse()
       System.out.println("带房客看房");
  
   //收中介费
   public void fare()
       System.out.println("收中介费");
  


       //代理实例的调用处理程序
       ProxyInvocationHandler pih = new ProxyInvocationHandler();
       pih.setRent(host); //将真实角色放置进去!
       Rent proxy = (Rent)pih.getProxy(); //动态生成对应的代理类!

动态代理代理某一类业务

一个动态代理可以代理多个类,代理的是接口!

动态代理固定模板

public class ProxyInvocationHandler implements InvocationHandler 
   private Object target;

   public void setTarget(Object target) 
       this.target = target;
  

   //生成代理类
   public Object getProxy()
       return Proxy.newProxyInstance(this.getClass().getClassLoader(),
               target.getClass().getInterfaces(),this);
  

   // proxy : 代理类
   // method : 代理类的调用处理程序的方法对象.
   public Object invoke(Object proxy, Method method, Object[] args) throws Throwable 
       log(method.getName());
       Object result = method.invoke(target, args);
       return result;
  

   public void log(String methodName)
       System.out.println("执行了"+methodName+"方法");
  


        //真实角色
        UserServiceImpl userService = new UserServiceImpl();
        //代理角色,不存在
        ProxyInvocationHandler pih = new ProxyInvocationHandler();
        //设置要代理的对象
        pih.setTarget(userService);
        UserService proxy =(UserService) pih.getProxy();
        proxy.add();
        proxy.delete();

AOP

纵向开发:

dao

|

service

|

servlet

|

前端

横向开发:

log->userservice

面向切面编程: 不改变原来的代码的情况下,实现了对原有功能的增强。

springaop:提供声明式事务,允许用户自定义切面。

通知(Advice):切面必须要完成的工作。即,它是类中的一个方法。

切入点(PointCut):切面通知 执行的 “地点”的定义。

五种类型的Advice

1.前置通知

2.后置通知

3.环绕通知

4.异常抛出通知

5.引介通知

AOP三种实现方式

导入aop织入包

SpringAPI实现

编写业务接口

编写业务实现类

编写增强类(5种通知类型) implements MethodBeforeAdvice implements AfterReturningAdvice

小说-悬疑:《楼下的房客》

如果包租公包租婆的72家房客都创业了,结果你无法相信|书乐寓言②

静态代理的实现-模拟中介代理房东出租房子给房客

(转)职业炒房客的秘诀 越不起眼的房子买了越赚钱

设计模式之中介模式

SQL 连接查询