spring笔记

spring

Spring是一个开源的Java EE开发框架。Spring框架的核心功能可以应用在任何Java应用程序中,但对Java EE平台上的Web应用程序有更好的扩展性。Spring框架的目标是使得Java EE应用程序的开发更加简捷,通过使用POJO为基础的编程模型促进良好的编程风格。

1.POJO和JavaBean的区别

(1)POJO 和JavaBean是我们常见的两个关键字,一般容易混淆,POJO全称是Plain Ordinary Java Object / Pure Old Java Object,中文可以翻译成:普通Java类,具有一部分getter/setter方法的那种类就可以称作POJO,但是JavaBean则比 POJO复杂很多, Java Bean 是可复用的组件,对 Java Bean 并没有严格的规范,理论上讲,任何一个 Java 类都可以是一个 Bean 。但通常情况下,由于 Java Bean 是被容器所创建(如 Tomcat) 的,所以 Java Bean 应具有一个无参的构造器。
(2)通常 Java Bean 还要实现 Serializable 接口用于实现 Bean 的持久性。 Java Bean 是不能被跨进程访问的。JavaBean是一种组件技术,就好像你做了一个扳子,而这个扳子会在很多地方被拿去用,这个扳子也提供多种功能(你可以拿这个扳子扳、锤、撬等等),而这个扳子就是一个组件。一般在web应用程序中建立一个数据库的映射对象时,我们只能称它为POJO。POJO(Plain Old Java Object)这个名字用来强调它是一个普通java对象,而不是一个特殊的对象,其主要用来指代那些没有遵从特定的Java对象模型、约定或框架(如EJB)的Java对象。理想地讲,一个POJO是一个不受任何限制的Java对象(除了Java语言规范)

2、Spring有哪些优点?

轻量级:Spring在大小和透明性方面绝对属于轻量级的,基础版本的Spring框架大约只有2MB。

控制反转(IoC):Spring使用控制反转技术实现了松耦合。依赖被注入到对象,而不是创建或寻找依赖对象。

面向切面编程(AOP): Spring支持面向切面编程,同时把应用的业务逻辑与系统的服务分离开来。

容器:Spring包含并管理应用程序对象的配置及生命周期。

MVC框架:Spring的web框架是一个设计优良的web MVC框架,很好的取代了一些web框架。

事务管理:Spring对下至本地业务上至全局业务(JAT)提供了统一的事务管理接口。

异常处理:Spring提供一个方便的API将特定技术的异常(由JDBC, Hibernate, 或JDO抛出)转化为一致的、Unchecked异常。

3、Spring 有两个核心部分:IoC 和AOP

​ (1) IoC:控制反转,把创建对象过程交给 Spring进行管理,Spring反向控制应用所需要使用的外部资源,spring控制的资源全部放置在Spring容器中,该容器成为IOC容器。
​ (2) AOP:面向切面,不修改源代码进行功能增强

4、Spring 特点

​ (1) 方便解耦,简化开发
​ (2) Aop编程支持
​ (3) 方便程序测试
​ (4) 方便和其他框架进行整合
​ (5) 方便进行事务操作
​ (6) 降低 API开发难度

5.Spring架构图、Spring由哪些部分组成

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dEOxMUJb-1642837266886)(A:\桌面\Java框架\img\spring框架结构)]

6.spring模块介绍:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2YsZAyO2-1642837266887)(A:\桌面\Java框架\img\spring模块功能)]

7.创建第一个项目

(1).使用idea创建普通Java项目

(2).导入 context、beans、core、expression、commons-logging(日志)依赖

(3).导入projectStruct

(4).创建普通类,创建普通类方法

package com.zwc;

public class User {
    public static void add(){
        System.out.print("add");
    }
}

(5).创建Spring配置文件,在配置文件中创建对象(bean1.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 配置User对象 -->
    <bean id="user" class="com.zwc.User"></bean> 
</beans>

(6).进行测试代码

@Test
    public void testAdd() {
        //1 加载 spring 配置文件 
        ApplicationContext context =
                new ClassPathXmlApplicationContext("bean1.xml");
        //2 获取配置创建的对象 
        User user = context.getBean("user", User.class);
        System.out.println(user);
        user.add();
    }
8. 耦合(Coupling):代码书写过程中所使用技术的结合紧密程度,用于衡量软件中各个模块之间的互联程度。
 内聚(Cohesion):代码书写过程中单个模块内部个部分间的联系,用于衡量软件中的各个功能模块内部的功能联系。
 工厂模式的发展
 UserServiceImpl——————————————————>UserDaoImpl


 UserServiceImpl———————>UserDaoFactory————————>UserDaoImpl


 UserServiceImpl—————————>UserDaoFactory————————>resouce.xml——————>UserDaoImpl


 UserServiceImpl————>(UserDaoFactory—*Spring雏形*——>resouce.xml)————>UserDaoImpl
9.IoC配置(XML格式)

bean:隶属于beans,定义spring资源,受此标签定义的资源受到spring控制
id:bean的名称,通过id获取bean资源
class:bean的类型
name:bean的名称,可以通过name获取bean,用于多人配合时bean起别名,用逗号间隔开
scope:
singleton:设定创建出的对象保存在spring容器中,是一个单例对象(加载spring容器时创建bean)
prototype:设定创建出的对象保存在spring容器中,是一个多例对象(获取对象时创建bean)
request、session、application、websocket:设定创建出的对象放置在web容器对应的位置
生命周期:init-method、destroy-method二者与是否单例相关
静态工厂与实例工厂:静态方法-静态工厂 创建实例,依赖实例子工厂对应的bean-实例工厂
DI(Dependency Injection):依赖注入,应用程序运行以来的资源有spring为期提供,资源进入程序的方式称为注入。(Ioc和Di是同一件事在不同角度看问题)
set注入:使用set方法的形式为bean提供资源
1).对要注入的资源设置set方法
2).将要注入的资源交给spring空中
3).使用property属性将资源注入到bean中,name是要注入的变量名,ref是要注入的bean的id
集合注入:array、list、set、map、props
构造器注入:使用构造方法的形式为bean提供资源,需要保证注入的属性与bean中一致,指的是顺序,类型一致。(有参构造函数注入,使用constructor-arg)type index(说明顺序,从0开始)
使用p命名空间简化配置:为bean注入属性值 p:propertyName p:property-ref
SpEL:所有格式统一使用value="#{…}"
properties文件:
1).加载命名空间的支持
xmlns:context=“http://www.springframework.org/schema/context”
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
2).引入properties文件
<context:property-placeholder location="classpath*:data.properties"/>
3).使用通配符
<property name="userName" value="${username}"/>
报错;Could not resolve placeholder ‘username’ in value “${username}” :classpath 与 classpath*
团队开发:使用import标签导入多个配置文件 <import resource="applicationContext-user.xml"/>
冲突问题:后定义的bean覆盖先定义的bean
ApplicationContext:
继承结构:
BeanFactory
ListableBeanFactory
ApplicationContext
ConfigurableApplicationContext
AbstractApplicationContext
AbstractRefreshableApplicationContext
AbstractRefreshableConfigApplicationContext
AbstractXmlApplicationContext
ClassPathXmlApplicationContext
1.ApplicationContext:是一个接口,提供了访问spring容器的API
2.ClassPathXmlApplicationContext:是一个类,实现了上述功能
3.ApplicationContext的顶层接口是BeanFactory
4.BeanFactory:定义了bean相关的基本操作
5.ApplicationContext在BeanFactory基础上追加了若干功能

对比BeanFactory
    1.BeanFactory创建的bean采用迟加载形式,使用才创建
    2.ApplicationContext创建的bean默认采用立即加载模式

FileSystemXmlApplicationContext:可以加载文件系统中任意位置的配置文件,而    ClassPathXMLApplicationContext只能加载类路径下的配置文件

第三方资源配置:
Druid配置:
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"></property> <property name="url" value="jdbc:mysql://localhost:3306/spring_db"></property> <property name="username" value="root"></property> <property name="password" value="root"></property> </bean>

10.注解开发

注解驱动的意义:
注解启动时使用注解的形式替代xml配置,将复杂的视频日嗯配置文件从工程中彻底消除掉。
<bean id="userService" class="UserServiceImpl" scope="prototype" init-method="init" destroy-method="destroy"></bean>
使用注解简化为:
@Component(“userService”)
@Scope("propetype)
public class UserServiceImpl implements …{
@PostConstruct
public void init(){}
@PreDestroy
public void Destroy(){}
}

常用注解:
启动注解功能:<context:component-scan base-package="packagename"/>
说明:
1).在进行扫包时,会对配置的包及其子包进行扫描
2).扫描过程是以文件夹递归形式进行
3).扫描时仅读取合法的java文件
4).扫描时仅读取spring可识别的注解
5).扫描结束后可将有效注解转化为spring对应的资源加入Ioc容器
(不管是XML额皮质方式还是注解形式最终都是将资源加载进入IoC容器,差别是读取方式不同)
bean的定义:
@Component(组件,写在类上方) @Controller(控制层) @Service(业务层) @Repository(数据层)
@prototype

整合第三方:(@Bean)

        @Component
        public class JDBCConfig {

            @Bean("dataSource")
            public static DruidDataSource getDataSouce(){
                DruidDataSource ds = new DruidDataSource();
                ds.setDriverClassName("com.mysql.jdbc.Driver");
                ds.setUrl("jdbc:mysql://localhost:3306/spring_db");
                ds.setName("root");
                ds.setPassword("root");
                return ds;
            }
        }

说明:
    1).因为第三方面bean无法在源码上进行修改,使用@Bean解决第三方bean的引入问题
    2).该注解用于替代XMl配置中静态工厂与实例工厂创建bean,不区分是否为静态或非静态
    3).@Bean所在类必须被spring扫描加载,否则该注解无法使用
@import(JDBCConfig.class) 导入第三方bean作为spring控制的资源
    1).@impoort注解在同一个类上,仅允许添加一次,如果需要导入多个,使用数组形式进行设定
    2).在被导入的类中可以继续使用@import导入其他资源
    3).@Bean所在的类可以使用导入的形式进入spring容器,无需声明为bean

bean的非引用类型注入:@Value()
仅支持非引用类型数据

bean的引用类型注入:
@Autowired 按类型配,如果有两个,按id配,如果都不行报错
@Qualifier(“name”) 指定id
@primary 提高优先级
@Inject @Named JSR330规范 与@Autowired和@Quaifier,@Rsourse JSR规范分name和id
加载properties文件
@Component(“bookDao”)
@PropertySource({“classpath:data.properties”,“classpath:abc.properties”})
public class BookDaoImpl implements BookDao {
@Value(" p a s s w o r d " ) p r i v a t e S t r i n g p a s s w o r d ; @ V a l u e ( " {password}") private String password; @Value(" password")privateStringpassword;@Value("{username}")
private String username;
@Value(" u s e r " ) p r i v a t e S t r i n g u ; @ V a l u e ( " {user}") private String u; @Value(" user")privateStringu;@Value("{pwd}")
private String p;
@Override
public void save() {
System.out.println(username+" "+password);
System.out.println(u);
System.out.println§;
System.out.println(“book dao running”);
}
}

纯注解格式:
@Configuration
@ComponentScan(“com.zwc”)

bean加载支持:@DependsOn:控制bean的加载顺序
微信订阅号,发布消息和订阅消息的bean加载顺序
双十一活动期间,零点前是A,零点后是B,策略B的操作数据为促销数据
加载顺序与促销数据的加载顺序
@Order :控制配置类的加载顺序
多种配置出现后的应急处理方案
@Lazy:控制bean延迟加载
程序灾难出现后对应的应急处理方案

11.整合第三方技术

整合mybatis:
spring环境:
1).实体类与表
2).业务接口与实现
3).数据层接口
4).Mybatis核心配置
5).Mybatis映射配置
6).客户端程序测试功能
7).spring核心配置文件
8).Druid数据源的应用

12.IoC底层原理:

IOC核心接口:
BeanFactory:
getBean(…):获取Bean
getBeanProvide:bean的供应商

12.Aop

Aop:面向切面编程,一种编程范式,隶属于软工范畴,指导开发者如何组织程序结构
Aop弥补了OOP的不足,基于OOP基础上进行横向开发
OOP规定程序开发以类为主题模型,一切围绕对象进行,完成某个任务线构建模型
AOP程序开发主要关注OOP开发中的共性的功能,一切围绕共性的功能进行,完成某个任务先构建可能遇到的所有共性功能。

相关概念
连接点:所有方法
切入点:具有共性功能的方法(要做)
通知:共性功能(要做)
切面:切入点与通知的关系(要做)
目标对象:简化运行的对象成为目标对象
织入:共性功能到原始功能的动作
代理:目标对象变化得到代理类这个过程成为代理

XML格式切面:
1).提取共性功能
2).制作一个通知类,定义一个方法用于完成一个共性功能
3).配制共性功能成为spring控制的bean
4).开启aop命名空间
5).配置AOP
```
aop:config
6).配置切入点
<aop:pointcut id=“pt” expression=“execution(* (…))”/>
7).配置切面(切入点与通知)
<aop:aspect ref=“myAdvice”>
8).配置切入点对应那个方法
<aop:before method=“function” pointcut-ref=“pt”></aop:before>
</aop:aspect>
</aop:config>

        ```

AspectJ:用于描述切入点和通知间的关系,是AOP的编程中的一个概念
AspectJ:是给予java语言的Aspect的实现

切入点:描述的是某个方法。
切入点表达式:切入点表达式是一个快速匹配方法描述的通配格式,类似于正则表达式
关键字(访问修饰符 返回值 包名.类名.方法名(参数)异常名)
关键字:描述表达式的匹配类型
访问修饰符:方法的访问控制权限控制符
类名:方法所在的类(此处可为配置接口名称)
异常:方法定义中缩指定抛出的异常
exexution(public User com.zwc.service.Userservice.findbyid(int))
execution:匹配制定方法
args:匹配参数
通配符:
* :单个独立的任意符号,可以独立出现
…:多个连续的任意符号
+:用于匹配子类类型

Aop通知类型:
前置通知:
后置通知:
返回后通知:
抛出异常后通知:
1).方法须设定Object类型的返回值,否则会拦截原始方法的返回。如果原始方法返回类型为voi,通知方法也可以设定返回值类型为void,最终返回null
2).方法需要在第一个参数位置设定ProceedingsJoinPoint对象,通过对象调用proceed()方法,实现对原始方法的调用。如省略该参数,原始方法无法执行
3).使用proceed()方法调用原始方法时,因无法预知原始方法运行过程中是否会出现异常,强制抛出Throwable对象,封装原始方法中可能出现的异常信息。

        package com.zwc.aop;

    import org.aspectj.lang.ProceedingJoinPoint;
    
    public class AOPAdvice {
    
        public void before(){
            System.out.println("before");
        }
        public void after(){
            System.out.println("after");
        }
        public void afterReturning(){
            System.out.println("afterReturning");
        }
        public void afterThrowing(){
            System.out.println("afterThrowing");
        }
    
        public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
            System.out.println("around before");
            proceedingJoinPoint.proceed();
            System.out.println("around after");
        }
    }


    <aop:config>
                <aop:pointcut id="pt" expression="execution(* *..*(..))"/>
                <aop:aspect ref="myAdvice">
                    <aop:before method="after" pointcut-ref="pt"></aop:before>
                    <aop:after method="after" pointcut-ref="pt"></aop:after>
                    <aop:after-throwing method="afterThrowing" pointcut-ref="pt"></aop:after-throwing>
                    <aop:after-returning method="afterReturning" pointcut-ref="pt"></aop:after-returning>
                    <aop:around method="around" pointcut-ref="pt"></aop:around>
                </aop:aspect>
            </aop:config>

通知顺序:
当同一切入点配置了多个通知时,通知会存在运行的先后顺序,该顺序以通知配置顺序为准。

Aop配置注解
1.切入点最终体现为一种方法,无参无返回值,无实际方法内容,但不能是抽象方法
2.引入切入点时必须使用方法调用名称,方法后面的()不能省略
3.切面类中定义的切入点只能在当前类中使用,如果引用其他类中定义的切入点使用“类名.方法名()”引用
4.可以在通知类型注解后面加参数,实现xml配置中的属性。
AOP注解式通知顺序:
AOP使用XML配置情况下,通 知的执行顺序由配置顺序决定,在注解的情况下由于不存在配置顺序的概念
,参照通知所配置的方法名字符串对应的编码值顺序,可以简单理解为字母排序
同一个通知类中,相同通知类型以方法名排序为准
不同通知类中,以类名排序为准
使用@Order注解通过变更bean的加载顺序改变通知的加载顺序
企业开发经验:
通知方法名由3部分组成,分别是前缀、顺序编码、功能描述
前缀为固定字符串,无实际意义
顺序编码为6位以内的整数,通常3位即可,不足位补零
功能描述为该方法对应的实际通知功能:例 exception、strLenCheck
控制通知执行顺序使用顺序编码控制,使用时做一定空间预留
003使用,006使用,预留001、002.004、005、007、008
使用时从中段开始使用,方便后期做前置追加或后置追加
最终顺序以运行顺序为准,以测试结果为准

AOP注解驱动:
@EnableAspecJAutoProxy

13.装饰者模式–做增强

动态代理:JDK Proxy动态代理是针对对象做代理,要求对象具有接口实现,并对接口方法进行增强
CGLIB(COde Generate Library):Code生成类库
代理模式的选择:默认使用JDKproxy
<aop:config proxy-target-class=“false”></aop:config>
<aop:aspectj-autoproxy proxy-target-class="false/>
@EnableAspectAutoProxy(proxyTargetClass = false)
织入时机:
.java---->.class---->.class进入jvm---->运行字节码
编译期:运行速度快,灵活性差,编译即锁定
加载期:运行速度快,灵活性中,多次加载可变实现
运行期:运行速度慢,灵活性强,每次运行均可改变实现

14.事务
1.当数据库操作序列中个别操作失败时,提供一种方式使数据库状态恢复到正常状态,保障数据库即使在异常状态下仍能保持数据一致性
2.当出现并发访问数据库时,在多个访问间进行相互隔离,防止并发访问操作结果互相干扰
事务的特性:
    原子性:事务是一个不可分割的整体,其中的操作要么全执行,要么不执行
    一致性:事务前后数据的完整性必须保持一致
    隔离性:事务的隔离性十多个用户并发的访问数据时,数据库为每一个用户开启的事务,不被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。
    持久性:持久性是指一个事务一旦被提交,他对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对期有任何影响。
事务的隔离级别:
    脏读:允许提交未提交的信息
        原因:Read uncommitted
        解决方案:Read committed(表级解锁)
    不可重复读:读取过程中单个数据发生了变化
        解决方案:Repeatable read(行级写锁)
    幻读:读取过程中数据条目发生了变化
        解决方案:Serializable
Spring事务核心对象:
    JEE开发使用分层设计的思想进行,对于简单的业务层转调数据层的单一操作,事务开启 在业务层或者数据层并无太大差别,当业务中包含多个数据层的调用时,需要在业务层开启事务,对数据层中多个操作进行组合并归属于同一个事务进行处理。
    Spring为业务层提供了整套事务解决方案
        PlateformTransactionManager
            DataSouceTransactionManager:用于SpringJDBC 或Mybatis
            HibernateTransactionManager:适用于Hibernate3.0以上版本
            JpaTranactionManager:适用于Jpa
            JdoTranactionManager:适用于Jdo
            JtaTranactionManager:适用于Jta
                JPA(java Persistence API)JavaEE标准之一,为POJO提 供持久化标准规范,并规范了持久化开发的统一AP1,符合JPA规范的开发可以在不同的JPA框架 下运行。
                JDO(java Data Object )是Java对象持久化规范,用于存取某种 数据库中的对象,并提供标准化API。与JDBC相比,JDBC仅针对关系数据库进行操作,JDO可以扩展到关系数据库、文件、XML、对象数据库(ODBMS)等,可移植性更强
                JTA (java Transaction API)Java EE标准之一,允许应用程序 执行分布式事务处理。与JDBC相比,JDBC事务则被限定在一个单一的数据库连接,而一个JTA事 务可以有多个参与者,比如JDBC连接、JDO都可以参与到一个JTA事务中
        TransactionDefinition:定义了事务的基本信息
            String getName:
            boolean isReadyOnly:
            int getIsolationLevel:
            int getTimeout:
            int getPropagationBehavior:
        TransactionStatus:定义是诶在执行过程中某个时间点上的状态信息及对应的状态操作

编程式事务: PlatformTransactionManager ptm = new DataSourceTransactionManager(datasource)
TransactionDefinition td = new DefaultTransiactionDefinition();
TransactionStatus ts = ptm.getTransaction(td);

ptm.submit();
使用AOP控制事务:利用环绕式通知运行期织入
声明式:tx

事务传播行为:事务协调员对事务管理员所携带的事务的处理态度
事务管理员:method1里的事务
事务协调员:method2里的事务

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值