zoukankan      html  css  js  c++  java
  • Spring学习

    Spring简介

      Spring是分层的JavaSE/EE应用full-stack轻量级开源框架

    Spring的体系结构

      底层核心容器

       Beans

        Core             

        Context

        SpringEL表达式

      中间层技术

        AOP

        Aspects

      应用层技术

        数据访问与数据集成

        Web集成

        Web实现

    Spring优势

      1、方便解耦,简化开发

      2、方便集成各种优秀的框架

      3、方便程序的测试

      4、AOP编程的支持

      5、声明式事务的支持

    IOC简介

      IOC(Inversion Of Control):控制反转,Spring反向控制应用程序所需要使用的外部资源(降低程序之间的耦合)

      IOC 容器:就是具有依赖注入功能的容器,是可以创建对象的容器,IOC容器负责实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。通常new一个实例,控制权由程序员控制,而"控制反转"是指new实例工作不由程序员来做而是交给Spring容器来做。。在Spring中BeanFactory是IOC容器的实际代表者。

      DI(依赖注入Dependency injection) :在容器创建对象后,处理对象的依赖关系。当前类需要用到的其他类对象的时候,由spring为我们提供,我们只需要在配置文件中说明依赖之间的关系

      IOC底层是通过工厂类+xml文件的方式去实现解耦并将所有的对象在web容器启动时创建。

    xml形式的spring框架搭建

    1、配置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:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
           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
           http://www.springframework.org/schema/tx
           http://www.springframework.org/schema/tx/spring-tx.xsd
            http://www.springframework.org/schema/aop
           https://www.springframework.org/schema/aop/spring-aop.xsd">

    2、加载配置文件mybatis.properties

     <!--1.加载配置资源-->
        <context:property-placeholder location="classpath:mybatis.properties"/>

    3、配置druid外部资源

    1 <!--3.配置外部资源德鲁伊-->
    2     <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
    3         <property name="driverClassName" value="${jdbc.driver}"/>
    4         <property name="url" value="${jdbc.url}"/>
    5         <property name="username" value="${jdbc.username}"/>
    6         <property name="password" value="${jdbc.pwd}"/>
    7     </bean>

    4、配置mybatis

     1 <!--4.1配置工厂类对象
     2       主要分析mybatis核心文件中有那些部分需要配置 比如 起别名 插件 资源环境(可以直接引用德鲁伊的)
     3       -->
     4     <bean  class="org.mybatis.spring.SqlSessionFactoryBean">
     5         <property name="dataSource" ref="dataSource"/>  <!--环境资源-->
     6         <property name="typeAliasesPackage" value="com.itheima.domain"/>  <!--起别名-->
     7     </bean>
     8       <!--4.2配置映射配置文件扫描-->
     9     <bean  class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    10         <property name="basePackage" value="com.itheima.mapper"/> <!--映射路径-->
    11     </bean>

    5、配置依赖注入(包括IOC与DI)

    1 <bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl">
    2         <property name="accountMapper" ref="accountMapper"/>
    3  </bean>

    6、声明事务管理对象

     1 <!-- 5.声明事务管理对象
     2    主要使用的是正对下面三种的事务处理的类,现在使用的是mybatis 
     3         DataSourceTransactionManager   jdbc/mybatis
     4         HibernateTransactionManager   Hibernate
     5         JtaTransactionManager         分布式事务管理
     6    -->
     7     <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
     8         <!--注入数据源-->
     9         <property name="dataSource" ref="dataSource"/>
    10     </bean>

    7、声明事务通知

    1  <!--6.声明事务通知 导入的必须是 tx的 千万不要选错成che那种-->
    2     <tx:advice id="txAdvice" transaction-manager="transactionManager">
    3         <tx:attributes>
    4             <tx:method name="*"/> <!--REQUIRED:如果有事务,就用当前事务,如果没事务,则开启一个新的事务 都为默认设置 一般更新修改操作-->
    5             <tx:method name="find*" propagation="SUPPORTS" read-only="true"/>
    6             <!--一般对查询类的方法进行过滤 传播方式为support为,当有事务就加入事务,没有事务就没有,为只读操作
    7             一般用于查询操作-->
    8         </tx:attributes>
    9     </tx:advice>

    8、设置事务的切点

    1     <!--7. 设置事务的切点-->
    2     <aop:config > <!--这里的proxy-target-class设置为true,动态代理就是cglib模式下的动态代理-->
    3         <aop:pointcut id="pt" expression="execution(* com.itheima.service.*.*(..))"/>
    4         <aop:advisor advice-ref="txAdvice" pointcut-ref="pt"/> <!--事务的切点配置需要是advisor-->
    5     </aop:config>

    9、aop 设置  配置切面

    1  <!-- 8.设置切面-->
    2     <bean id="advice" class="com.itheima.aop.AopAdvice"/>

    10、织入

    1 <!-- 9.配置织入-->
    2     <aop:config >
    3         <aop:pointcut id="pi" expression="execution(* com.itheima.service.*.*(..))"/> <!--设置切点-->
    4         <aop:aspect id="" ref="advice"> <!--ref的属性值为通知-->
    5             <aop:around method="around" pointcut-ref="pi"/>
    6         </aop:aspect>
    7     </aop:config>

    纯注解的形式spring框架搭建

    1、配置spring核心配置类

    1 @ContextConfiguration//定义为核心类
    2 @ComponentScan("com.itheima")//设置注解包扫描路径支持
    3 @Import({MyBatisC.class, DruidC.class, TransactionC.class})//导入第三方进ioc容器
    4 @EnableTransactionManagement(proxyTargetClass = true)//开启事务注解支持
    5 @EnableAspectJAutoProxy(proxyTargetClass = true)//开启aop注解支持
    6 public class SpringConfig {
    7 }
    //SpringConfig为核心配置类

    2、配置第三方类

     1 //德鲁伊的外部类
     2 @PropertySource("classpath:mybatis.properties")//加载外部配置文件
     3 public class DruidC {
     4 
     5     @Value("${jdbc.driver}")
     6     private String driver;
     7     @Value("${jdbc.url}")
     8     private String url;
     9     @Value("${jdbc.username}")
    10     private String username;
    11     @Value("${jdbc.pwd}")
    12     private String pwd;
    13 
    14     //配置druid
    15     @Bean("dataSource")
    16     public DataSource getDataSource(){
    17         //创建java对象
    18         DruidDataSource ds = new DruidDataSource();
    19         ds.setDriverClassName(driver);
    20         ds.setUrl(url);
    21         ds.setUsername(username);
    22         ds.setPassword(pwd);
    23 
    24         return ds;
    25     }
    26 }
    27 
    28 //mybatis的外部类
    29 public class MyBatisC {
    30     @Bean   //可以不加id spring已经搞好了,与xml一致  方法的参数中的值是默认有Autowired 所以不写是可以查询到结果的
    31     public SqlSessionFactoryBean getSqlSessionFactoryBean(@Qualifier("dataSource") DataSource dataSource){
    32         SqlSessionFactoryBean sb = new SqlSessionFactoryBean();//创建对象
    33         sb.setDataSource(dataSource);//获取资源
    34         sb.setTypeAliasesPackage("com.itheima.domain");//设置别名  可以使用配置文件读取
    35         return sb;
    36     }
    37     @Bean//创建获取MapperScannerConfigurer对象  可以不加id
    38     public MapperScannerConfigurer getMapperScannerConfigurer(){
    39         MapperScannerConfigurer msc = new MapperScannerConfigurer();
    40         msc.setBasePackage("com.itheima.mapper");//指定创建的映射文件路径,将其注入ioc
    41         return msc;
    42     }
    43 }
    44 
    45 //事务的外部类
    46 public class TransactionC {
    47 
    48     @Bean
    49     public PlatformTransactionManager getPlatformTransactionManager(@Autowired DataSource dataSource) {
    50         return new DataSourceTransactionManager(dataSource);
    51     }
    52 }

    3、配置切面类 

     1 @Component//注入ioc
     2 @Aspect//标记为切面类
     3 public class AopAdvice {
     4 
     5     @Around("pt()")
     6     public Object around(ProceedingJoinPoint pjp){
     7         System.out.println("我是环绕的前置通知...");
     8         Object ret=null;
     9         try {
    10              ret = pjp.proceed();
    11             System.out.println("我是环绕的后置通知...");
    12         } catch (Throwable throwable) {
    13             throwable.printStackTrace();
    14             System.out.println("我是环绕的异常通知..");
    15         }finally {
    16             System.out.println("我是环绕的最终通知..");
    17         }
    18         return null;
    19     }
    20 
    21     @Pointcut("execution(* com.itheima.service.*.*(..))")//设置切点
    22     public void pt(){
    23     }
    24 }

    4、将实现类 注入ioc容器,开启tx事务,进行aop加强

     1 @Service//注入ioc容器
     2 @Transactional(propagation = Propagation.NEVER)//定义该类具有事务
     3 public class AccountServiceImpl implements AccountService {
     4     @Autowired//依赖注入
     5     public AccountMapper accountMapper;
     6 
     7     public void updateAccount(String oName, String iName, double money) {
     8 
     9         accountMapper.outUpdate(oName,money);
    10         accountMapper.inUpdate(iName,money);
    11     }
    12 }

    5、

     1 public class AccountController {
     2 
     3     @Test
     4     public void test(){
     5         //加载核心配置
     6         ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfig.class);
     7         AccountService accountService = ac.getBean(AccountService.class);
     8         accountService.updateAccount("jack","lucy",250);
     9     }
    10 }

    IOC配置

    • bean

    作用:定义spring中的资源,此标签定义的资源将受到spring控制

    格式:

    1 <beans>
    2     <bean />
    3 </beans>

    举例:

    1 <bean id="beanId" name="beanName1,beanName2" class="ClassName" scope="singleton"></bean>

    属性解析:

    id:bean的名称,通过id值获取bean      class:bean的类型(类的全限定类名)

    name:bean的名称,可以通过name值获取bean,用于多人配合时给bean起别名

    scope:定义bean的作用范围   

        spring默认的值为singleton 表示该对象是个单例的对象

                prototype 表是该对象是个多例的对象

                request、session、application、 websocket :设定创建出的对象放置在web

                  容器对应的位置

    spring容器中的bean定义冲突问题

      同id的bean,后定一的覆盖先定义的

      导入配置文件可以理解为浆倒入的配置文件赋值zhantie到对应位置

      导入配置文件的顺序与位置不同可能会导致最终程序运行结果不同

    • set注入

    归属 bean标签 作用使用set方法的形式为bean提供资源

    格式: <property />   一个bean可以有多个property标签

    举例:

    <property name="propertyName" value="propertyValue"( ref="beanId"/>

    name:对应bean中的属性名,要求该属性必须提供可访问的set方法(严格规范为此名称是set方法对应名称)

    value:设定非引用类型属性对应的值,不能与ref同时使用

    ref:设定引用类型属性对应bean的id ,不能与value同时使用

    • 构造器注入

    归属 bean标签  作用:使用构造方法的形式为bean提供资源,兼容早期遗留系统的升级工作(部分类没有提供无参构造,只有有参构造)

    格式:  <constructor-arg />

    举例:

    基本属性

    <constructor-arg name="argsName" value="argsValue />

    name:对应bean中的构造方法所携带的参数名

    value:设定非引用类型构造方法参数对应的值,不能与ref同时使用

    其他属性:

    <constructor-arg index="arg-index" type="arg-type" ref="beanId"/>

    ref:设定引用类型构造方法参数对应bean的id ,不能与value同时使用

    <bean id="beanId" class="....."></bean>

    type :设定构造方法参数的类型,用于按类型匹配参数或进行类型校验

    index :设定构造方法参数的位置,用于按位置匹配参数,参数index值从0开始计数

    • 集合类型数据注入

    归属:property标签 或 constructor-arg标签

    作用:注入集合数据类型属性

    格式:

    1 <property>
    2     <list></list>
    3 </property>

    举例:

     1 //集合类型数据注入——list
     2 <property name="al">
     3     <list>
     4         <value>itheima</value>
     5         <value>66666</value>
     6     </list>
     7 </property>
     8 
     9 //集合类型数据注入——props
    10 <property name="properties">
    11     <props>
    12         <prop key="name">itheima666</prop>
    13         <prop key="value">666666</prop>
    14     </props>
    15 </property>
    16 
    17 //集合类型数据注入——map
    18 <property name="hm">
    19     <map>
    20         <entry key="name" value="itheima66666"/>
    21         <entry key="value" value="6666666666"/>
    22     </map>
    23 </property>
    • properties文件

    Spring读取外部文件的机制,使用读取到的数据为bean的属性赋值

    1.开启context命名空间支持

    xmlns:context="http://www.springframework.org/schema/context"

    2、加载指定的properties文件

    <context:property-placeholder location="classpath:filename.properties">

    3、读取数据

    使用${.....}获取数据

    注意如果需要加载所有的properties文件,可以使用*.properties表示加载所有的properties文件,如果是多个的话,在location后面加 逗号 , 但是当找不到时会报错(有风险)

    • 团队开发

    归属:beans标签   作用:在当前配置文件中导入其他配置文件中的项

    格式:<import />

    基本属性:

    <import resource=“config.xml"/>

    注解模式

    • 注解扫描功能

    启动注解扫描,加载类中配置的注解项

    <context:component-scan base-package="packageName"/>

     

    在进行包所扫描时,会对配置的包及其子包中所有文件进行扫描

     

    扫描过程是以文件夹递归迭代的形式进行的

     

    扫描过程仅读取合法的java文件

     

    扫描时仅读取spring可识别的注解

     

    扫描结束后会将可识别的有效注解转化为spring对应的资源加入IoC容器

    • bean

    名称

    @Component @Controller @Service @Repository

    定义在类的上方

    作用:设置该类为spring管理的bean

    属性为value 定义bean的访问id 默认

    注解bean的作用域scope定义在类上

    @scope  

    默认属性value 值为singleton

    @value  bean的非应用数据类型属性注入

    作用:设置对应属性的值或者方法进行传参

    注意:仅支持非引用数据类型数据,赋值时对所有的方法的参数全部赋值

    @Autowired、@Qualifier     bean的引用类型属性注入

    位置:方法定义上方,属性定义上方

    作用:设置对应属性的对象或对方法进行引用类型传参

    举例:

     1 @Autowired(required = false) 2 @Qualifier("userDao") 3 private UserDao userDao; 

    说明:@Autowired默认按类型装配,指定@Qualifier后可以指定自动装配的bean的id

        方法的参数上如果不写是默认自动装配的

    • 加载第三方资源

    名称 @Bean   位置:方法定义上

    作用:设置该方法的返回值作为spring管理的bean

    举例:

     1 @Bean("dataSource") 2 public DruidDataSource createDataSource() { return ……; } 

    说明:

    因为第三方bean无法在其源码上进行修改,使用@Bean解决第三方bean的引入问题

    该注解用于替代XML配置中的静态工厂与实例工厂创建bean,不区分方法是否为静态或非静态

    @Bean所在的类必须被spring扫描加载,否则该注解无法生效

    加载properties文件

    名称:@propertySource

    位置:类的上方   作用:加载配置文件的属性值

    举例:

    1 @PropertySource(value = "classpath:filename.properties")
    2 public class ClassName {
    3     @Value("${propertiesAttributeName}")
    4     private String attributeName;
    5 }

    注意:不支持*通配格式,一旦加载,所有spring控制的bean中均可使用对应属性值

    • 纯除注解格式

    名称:@Configuration、@ComponentScan

    位置:定义在类上方,该类为核心加载类

    作用:作用:设置当前类为spring核心配置加载类

    举例:

    1 @ContextConfiguration//定义为核心类
    2 @ComponentScan("com.itheima")//设置注解包扫描路径支持
    3 @Import({MyBatisC.class, DruidC.class, TransactionC.class})//导入第三方进ioc容器
    4 @EnableTransactionManagement(proxyTargetClass = true)//开启事务注解支持
    5 @EnableAspectJAutoProxy(proxyTargetClass = true)//开启aop注解支持
    6 public class SpringConfig {
    7  }

    说明:

     

    核心配合类用于替换spring核心配置文件,此类可以设置空的,不设置变量与属性

    @ComponentScan 开启注解扫描包路径

    @Import  导入第三方进入ioc容器  第三方必须这样,否则无效

    @EnableTransactionManagement(proxyTargetClass = true)//开启事务注解支持

    @EnableAspectJAutoProxy(proxyTargetClass = true)  开启aop注解支持 

    注意:proxyTargetClass 是动态代理模式  默认为jdk的proxy模式,true就为cglib模式

    • 依赖加载

    @DependsOn

     

    位置:bean定义的位置(类上或方法上)

     

    作用:控制bean的加载顺序,使其在指定bean加载完毕后再加载

    说明:

     

      配置在方法上,使@DependsOn指定的bean优先于@Bean配置的bean进行加载

     

      配置在类上,使@DependsOn指定的bean优先于当前类中所有@Bean配置的bean进行加载

     

      配置在类上,使@DependsOn指定的bean优先于@Component等配置的bean进行加载

     

    @Order

     

      位置:配置类定义的位置(类上)

     

      作用:控制配置类的加载顺序

    @Lazy

     

      位置:bean定义的位置(类上或方法上)

     

      作用:控制bean的加载时机,使其延迟加载

    AOP简介

      AOP(Aspect Oriented Programing)面向切面编程,一种编程范式,隶属于软工范畴,指导开发者如何组织程序结构

    目标:将软件开发由手工制作走向半自动化/全自动化阶段,实现“插拔式组件体系结构”搭建

    AOP优势

     

      提高代码的可重用性

     

      业务代码编码更简洁

     

      业务代码维护更高效

     

      业务功能扩展更便捷

    AOP开发过程

    • 开发阶段(开发者完成)

      • 正常的制作程序

      • 将非共性功能开发到对应的目标对象类中,并制作成切入点方法

      • 将共性功能独立开发出来,制作成通知

      • 在配置文件中,声明切入点

      • 在配置文件中,声明切入点通知间的关系(含通知类型),即切面

    • 运行阶段(AOP完成)

      • Spring容器加载配置文件,监控所有配置的切入点方法的执行

      • 当监控到切入点方法被运行,使用代理机制,动态创建目标对象代理对象,根据通知类别,在代理对象的对应位置将通知对应的功能织入,完成完整的代码逻辑并运行

    AOP配置

    • aop:config

    作用:设置AOP  归属beans标签

    • aop:aspect

    作用:设置具体的AOP通知对应的切入点     归属:aop:config标签

    • aop:pointcut

    作用:设置切入点      归属:aop:config标签、aop:aspect标签

    基本属性:

    • id :识别切入点的名称 ---->切入点描述的是某个方法

    • expression :切入点表达式 ---->切入点表达式是一个快速匹配方法描述的通配格式,类似于正则表达式

      切入点表达式格式:关键字(访问修饰符  返回值  包名.类名.方法名(参数)异常名)

        *:单个独立的任意符号,可以独立出现,也可以作为前缀或者后缀的匹配符出现

        .. :多个连续的任意符号,可以独立出现,常用于简化包名与参数的书写

        +:专用于匹配子类类型

    1 <beans>
    2     <aop:config>
    3     <aop:pointcut id="pointcutId" expression="……"/>  可以定义在config中
    4     <aop:aspect ref="beanId">……</aop:aspect>
    5     <aop:aspect>
    6         <aop:pointcut id="pointcutId" expression="* *.com.itheima.service.*.*(..)"/>
    7     </aop:aspect>
    8 </aop:config>
    9 </beans>    
    • AOP的通知类型共5种

     

        前置通知:原始方法执行前执行,如果通知中抛出异常,阻止原始方法运行

        aop:before  作用:设置前置通知

    应用:数据校验

        后置通知:原始方法执行后执行,无论原始方法中是否出现异常,都将执行通知

        aop:after-returning 作用设置后置通知

    应用:现场清理

     

        最终通知:原始方法正常执行完毕并返回结果后执行,如果原始方法中抛出异常,无法执行

        aop:after 作用:设置最终通知

    应用:返回值相关数据处理

     

        异常通知:原始方法抛出异常后执行,如果原始方法没有抛出异常,无法执行

        aop:after-throwing 作用设置异常通知

    应用:对原始方法中出现的异常信息进行处理

     

        环绕通知:在原始方法执行前后均有对应执行执行,还可以阻止原始方法的执行

        aop:around  作用:设置环绕通知

    应用:十分强大,可以做任何事情

    五个通知都有的基本属性:

    • method :在通知类中设置当前通知类别对应的方法

    • pointcut :设置当前通知对应的切入点表达式,与pointcut-ref属性冲突

    • pointcut-ref :设置当前通知对应的切入点id,与pointcut属性冲突

    注解AOP

    @Aspect

     

    位置:类定义上方     作用:设置当前类为切面类

     

    @Pointcut

    位置:方法定义上方  作用:使用当前方法名作为切入点引用名称

      注意:被修饰的方法忽略其业务功能,格式设定为无参无返回值的方法,方法体内空实现(非抽象)

    五大通知

    @Before @After @AfterReturning @AfterThrowing @Around

    事务管理

      J2EE开发使用分层设计的思想进行,对于简单的业务层转调数据层的单一操作,事务开启在业务层或者数据层并无太大差别,当业务中包含多个数据层的调用时,需要在业务层开启事务,对数据层中多个操作进行组合并归属于同一个事务进行处理

      Spring为业务层提供了整套的事务解决方案

        PlatformTransactionManager //此接口定义了事务的基本操作

        TransactionDefinition  //此接口定义了事务的基本信息

        TransactionStatus   //此接口定义了事务在执行过程中某个时间点上的状态信息及对应的状态操作

      平台事务管理器实现类

    • DataSourceTransactionManager 适用于Spring JDBC或MyBatis

    • HibernateTransactionManager 适用于Hibernate3.0及以上版本

    • JpaTransactionManager 适用于JPA

    • JdoTransactionManager 适用于JDO

    • JtaTransactionManager 适用于JTA 

    tx:advice

    归属:beans标签  作用:专用于声明事务通知

     

    基本属性:

    1 <beans>
    2     <tx:advice id="txAdvice" transaction-manager="txManager">
    3     </tx:advice>
    4 </beans>

      id :用于配置aop时指定通知器的id

      transaction-manager :指定事务管理器bean

    tx:attributes

    归属:tx:advice标签  作用:定义通知属性

    1 <tx:advice id="txAdvice" transaction-manager="txManager">
    2     <tx:attributes>
    3     </tx:attributes>
    4 </tx:advice>

    tx:method

    归属:tx:attribute标签  作用:设置具体的事务属性

    <tx:attributes>
        <tx:method name="*" read-only="false" />
        <tx:method name="get*" read-only="true" />
    </tx:attributes>

    @Transactional

    位置:方法定义上方,类定义上方,接口定义上方

    作用:设置当前类/接口中所有方法或具体方法开启事务,并指定相关事务属性

    tx:annotation-driven

    归属:beans标签

    作用:开启事务注解驱动,并指定对应的事务管理器

    @EnableTransactionManagement

    位置:Spring注解配置类上方

    作用:开启注解驱动,等同XML格式中的注解驱动

  • 相关阅读:
    TP5常用函数总结1
    swiper 自定义的一些需求
    jQuery 点击元素以外任意地方隐藏该元素
    fastadmin中编辑时的fieldlist选项类型,如何跟数据库里的保持一致,并且显示匹配的样式
    leetcode——63. 不同路径 II
    leetcode——62.不同路径
    数组标签结束,下一个标签,动态规划
    leetcode——48. 旋转图像
    leetcode——45. 跳跃游戏 II
    leetcode——41. 缺失的第一个正数
  • 原文地址:https://www.cnblogs.com/luckysupermarket/p/13584848.html
Copyright © 2011-2022 走看看