当前位置: 首页 > news >正文

无锡响应式网站制作最好的网站建设系统

无锡响应式网站制作,最好的网站建设系统,信息网络传播视听节目许可证,网站动态页面打不开文章目录Spring1 Spring 框架中用到的设计模式2 Spring 事务、隔离级别3 单例 Bean 是线程安全的吗Spring IOC1 Spring 容器#xff1a;BeanFactory ApplicationContext2 依赖注入的两种方式3 Bean 的生命周期4 依赖注入的四个注解5 如何解决循环依赖Spring AOP1 基本概… 文章目录Spring1 Spring 框架中用到的设计模式2 Spring 事务、隔离级别3 单例 Bean 是线程安全的吗Spring IOC1 Spring 容器BeanFactory ApplicationContext2 依赖注入的两种方式3 Bean 的生命周期4 依赖注入的四个注解5 如何解决循环依赖Spring AOP1 基本概念2 通知的执行顺序3 Spring AOP 和 AspectJ 有什么区别动态代理与静态代理4 动态代理JDK / CGLIBSpring MVC1 作用2 Spring MVC 执行流程Spring Boot1 SpringBootApplication 做了哪些事2 Spring Boot 自动装配原理Spring Cloud1 CAPSpring 1 Spring 框架中用到的设计模式 参考Spring 中的设计模式 工厂模式 Spring 通过 BeanFactory、ApplicationContext 创建 Bean 对象单例模式 Bean 默认都是单例的代理模式 AOP 功能的实现基于代理模式模板模式 xxxTemplate例如 RestTemplate 等使用了模板模式适配器模式 Spring AOP 的增强或通知Advice例如 ControllerAdvice使用到了适配器模式Spring MVC 中用到了适配器模式适配 Controller 2 Spring 事务、隔离级别 一般使用 Transactional 注解方式实现只能应用到 public 方法上否则不生效事务传播解决业务层方法之间互相调用的事务问题 传播行为解释PROPAGATION_REQUIREDTransactional注解默认使用。如果当前存在事务则加入该事务变成了同一事务只要一个方法回滚整个事务均回滚如果当前没有事务则创建一个新的事务PROPAGATION_REQUIRES_NEW创建一个新的事务如果当前存在事务则把当前事务挂起。也就是说不管外部方法是否开启事务会新开启自己的事务且开启的事务相互独立互不干扰PROPAGATION_NESTED如果当前存在事务则创建一个事务作为当前事务的嵌套事务来运行如果当前没有事务则等价于 PROPAGATION_REQUIREDPROPAGATION_MANDATORY如果当前存在事务则加入该事务如果当前没有事务则抛出异常 隔离级别类似于 MySQL 隔离级别解释ISOLATION_DEFAULT默认的隔离级别MySQL 默认采用的 REPEATABLE_READ 隔离级别Oracle 默认采用的 READ_COMMITTED 隔离级别ISOLATION_READ_UNCOMMITTED允许读取尚未提交的数据变更可能会导致 脏读、幻读或不可重复读ISOLATION_READ_COMMITTED允许读取并发事务已提交的数据可以阻止脏读但是幻读或不可重复读仍有可能发生ISOLATION_REPEATABLE_READ对同一字段的多次读取结果都是一致的除非数据是被本身事务自己所修改可以阻止脏读和不可重复读但幻读仍有可能发生ISOLATION_SERIALIZABLE所有事务依次执行这样事务之间就不可能产生干扰可以防止脏读、不可重复读以及幻读Transactional(rollbackFor MyException.class) 注解 如果类或者方法加了这个注解那么这个类里面的方法抛出异常就会回滚数据库里面的数据也会回滚 在 Transactional 注解中如果不配置 rollbackFor 属性,那么事务只会在遇到 RuntimeException 的时候才会回滚加上 rollbackForException.class 可以让事务在遇到自定义的非运行时异常时也回滚 3 单例 Bean 是线程安全的吗 不是Spring 框架并没有对单例 Bean 进行多线程的封装处理大部分时候 Bean 是无状态的比如 dao 无状态即不会保存数据所以大部分 Bean 是线程安全的如果 Bean 有状态的话需要开发者保证线程安全最简单的就是改变 Bean 的作用域把 singleton 变更为 prototype 这样请求 Bean 相当于 new Bean()就可以保证线程安全了 Spring IOC 1 Spring 容器BeanFactory ApplicationContext BeanFactory 和 ApplicationContext 是 Spring 的两大核心接口都可以当做 Spring 的容器 ApplicationContext 是BeanFactory 的子接口 BeanFactroy 采用的是 延迟加载 形式来注入 Bean 的即只有在使用到某个 Bean 时调用getBean()才对该 Bean 进行实例化 这样导致不能发现一些存在的 Spring 的配置问题如果Bean的某一个属性没有注入BeanFacotry 加载后直至第一次使用调用 getBean 方法才会抛出异常是一种低级的容器类似于一个 HashMapKey 是 BeanNameValue 是 Bean 实例通常只提供注册put获取get这两个功能 ApplicationContext 在容器启动时一次性创建了所有的 Bean把创建资源的过程放在服务器启动时。这样在容器启动时就可以发现 Spring 中存在的配置错误这样有利于检查所依赖属性是否注入。 ApplicationContext 启动后预载入所有的单实例Bean通过预载入单实例 Bean确保当需要的时候就不用等待 2 依赖注入的两种方式 使用 setter 方法 - 容器通过调用无参构造器或无参static工厂方法实例化 Bean 之后调用该 Bean 的 setter 方法 - 用于实现可选依赖适合设置少量属性 使用有参构造器 - 构造器依赖注入通过容器触发一个类的构造器来实现的 - 用于实现强制依赖适合设置大量属性 3 Bean 的生命周期 参考链接 Bean 自身的四个基础步骤 实例化 Instantiation调用构造函数执行构造函数的属性注入属性赋值 Populate执行 setter 的属性注入初始化 Initialization调用自定义的 Bean 初始化方法销毁 Destruction调用自定义的 Bean 销毁方法 指定 Bean 的初始化方法和销毁方法一般在配置类使用注解 Bean(initMethod myInit,destroyMethod myDestory) 另外在四个基础步骤上添加了一些 Bean级生命周期方法、容器级生命周期方法实现了 AOP 的功能 Bean级生命周期方法Bean 类直接实现接口的方法这些接口包括 BeanNameAware、BeanFactoryAware、ApplicationContextAware、InitializingBean、DisposableBean 等只对当前 Bean 产生影响容器级生命周期方法BeanPostProcessor初始化前后 和它的子类 InstantiationAwareBeanPostProcessor实例化前后 的一些方法对多个 Bean 产生影响 4 依赖注入的四个注解 注解作用范围Autowired按类型自动装配构造方法、成员变量、Setter 方法Qualifier按名称自动装配需要和 Autowired 搭配使用成员变量、Setter 方法Resource按名称或类型自动装配未指定规则时默认先按名称装配找不到满足要求的 bean再按类型装配成员变量、Setter 方法Value注入 int / float / String 等基本数据类型成员变量、Setter 方法 5 如何解决循环依赖 参考链接 Spring 能解决循环依赖的前置条件 循环依赖的 Bean 必须是单例发生的循环依赖 包含 Setter 注入发生在 Bean 属性赋值阶段而不能解决 只有 构造器注入时发生在 Bean 实例化阶段发生的循环依赖具体参考下图 情况3可行4不可行的原因 Spring 在创建 Bean 的时候默认是按照自然排序来进行创建的如果 A 使用构造器注入 B则 A 无法被创建 三级缓存结构 一级缓存 —— 单例池 singletonObjects存放已经创建完成的 Bean 对象二级缓存 —— 早期曝光对象 earlySingletonObjects 存放三级缓存工厂创建的 Bean 实例化后的对象或代理后的对象三级缓存 —— 早期曝光对象工厂 singletonFactories如果 Bean 被 AOP 代理通过对应的工厂获取到的是代理后的对象否则获取到的是 实例化阶段没有经过属性赋值和初始化 的对象获取后放入二级缓存 在给 B 注入的时候为什么要注入一个代理对象 对 A 进行了 AOP 代理时说明希望从容器中获取到的就是 A 代理后的对象而不是 A 本身因此把A当作依赖进行注入时也要注入它的代理对象 三级缓存的作用 延迟对实例化阶段生成的对象的代理只有真正发生循环依赖的时候才去提前生成代理对象否则只会创建一个工厂并将其放入到三级缓存中但是不会通过工厂真正创建对象 只用二级缓存能解决循环依赖吗 如果使用二级缓存解决循环依赖意味着所有 Bean 在实例化后就要完成 AOP 代理这样违背了 Spring 设计的原则在 Bean 生命周期的最后一步完成 AOP 代理而不是在实例化后立刻进行 AOP 代理 解决流程 A、B 两个类发生循环引用时在 A 实例化后使用实例化后的对象创建一个对象工厂并添加到三级缓存中A 实例化后进行属性注入时会创建B同时 B 又依赖了 A此时 getBean(a) 会从缓存中获取第一步先获取到三级缓存中的工厂第二步调用对象工工厂的 getObject() 获取到对应的对象将其注入 B 中B 创建完后将 B 再注入到 A 中此时 A 再完成后续操作循环依赖解决 A 没有被 AOP 代理时 A 被 AOP 代理时 Spring AOP 1 基本概念 AOP的作用作为面向对象的一种补充用于将那些与业务无关但却对多个对象产生影响的公共行为和逻辑抽取并封装为一个可重用的模块这个模块被命名为“切面”Aspect。切面可以减少系统中的重复代码降低模块间的耦合度同时提高系统的可维护性。可用于权限认证、日志、事务处理等 切面Aspect通知 切入点连接点Join Point可以被增强的方法Java 只支持方法成为连接点通知Advice切面的工作被称为通知切入点Pointcut实际增强的方法连接点的子集目标对象Target Object 被切面所通知的对象即被增强的对象织入Weaving把切面应用到目标对象并创建新的代理对象的过程 2 通知的执行顺序 Component(value enhanceClass) Aspect public class EnhanceClass {Before(value execution(* pojo.MyClass.add(..)))public void before() {System.out.println(前置通知);}AfterReturning(value execution(* pojo.MyClass.add(..)))public void afterReturning() {System.out.println(后置通知正常返回时才执行);}After(value execution(* pojo.MyClass.add(..)))public void after() {System.out.println(最终通知无论是否正常返回都执行);}AfterThrowing(value execution(* pojo.MyClass.add(..)))public void afterThrowing() {System.out.println(异常通知);}Around(value execution(* pojo.MyClass.add(..)))public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {System.out.println(环绕通知前);proceedingJoinPoint.proceed();System.out.println(环绕通知后);} }- 无异常时 1. around before advice 2. before advice 3. target method 4. around after advice 5. after advice 6. afterReturning advice- 有异常时 1. around before advice 2. before advice 3. target method 4. around after advice 5. after advice 6. afterThrowing advice 7. 异常发生3 Spring AOP 和 AspectJ 有什么区别动态代理与静态代理 Spring AOP 采用了动态代理AspectJ 采用了静态代理AspectJ 使用 静态代理AOP 框架会在编译阶段生成 AOP 代理类因此也称为编译时增强他会在编译阶段将切面织入到 Java 字节码中运行的时候就是增强之后的 AOP 对象Spring AOP 使用 动态代理AOP 框架不会去修改字节码而是每次运行时在内存中临时生成一个 AOP 对象这个AOP 对象包含了目标对象的全部方法并且在特定的切点做了增强处理并回调原对象的方法静态代理与动态代理区别在于生成 AOP 代理对象的时机不同AspectJ 的静态代理方式具有更好的性能但需要特定的编译器进行处理而 Spring AOP 则无需特定的编译器处理 4 动态代理JDK / CGLIB JDK动态代理 JDK 动态代理基于接口被代理的只能是接口如果方法不来自于接口则无法增强方法如果类没有实现接口则完全无法创建代理通过反射机制生成一个实现代理接口的类创建的代理类型也只能是接口类型而不能是具体的类JDK 动态代理根据对象实例建立代理实例先创建被代理对象才能创建代理对象基于接口实现的原因 JDK 动态代理生成的代理对象需要继承 Proxy 这个类在 Java 中类只能是单继承关系无法再继承一个代理类所以只能基于接口代理 新生成的代理对象的 Class 对象会继承 Proxy且实现所有的入参 interfaces 中的接口在实现的方法中实际是调用入参 InvocationHandler 的 invoke(..) 方法 代理类的定义和被代理对象没有关系和 InvocationHandler 的实现也没有关系而主要和接口数组有关动态创建了每个接口的实现代码即将调用请求转发给 InvocationHandler DEMO 接口与接口的实现 interface CanWalk {void walk(); }interface CanEat {void eat(); }class Human implements CanWalk, CanEat {Overridepublic void walk() {System.out.println(walk with human feet);}Overridepublic void eat() {System.out.println(eat with human mouth);} }class Fish implements CanEat {Overridepublic void eat() {System.out.println(eat with fish mouth);} }InvocationHandler 代理对象调用原生方法的时候最终实际上调用到的是 invoke() 方法然后 invoke() 方法调用了被代理对象的原生方法invoke() 的首个参数 o 代表的是代理对象本身不能传递给 method.invoke()否则会死循环 class MyInvocationHandler implements InvocationHandler {private Object realObject;public MyInvocationHandler(Object realObject) {this.realObject realObject;}/*** proxy :动态代理对象Proxy* method : 要调用的原生方法* args : 方法参数**/Overridepublic Object invoke(Object o, Method method, Object[] objects) throws Throwable {System.out.println(JDK dynamic proxy: write to log);method.invoke(realObject, objects); // realObject而非o!!return null;} }获取代理对象并执行增强方法 得到的代理对象只能被强转为传入工厂方法的接口之一而不能强转为某个类如下如果 proxyInstance 被强转为 Human 类型则出现运行时异常得到的代理对象是 Proxy 的子类调用 Proxy.newProxyInstance(ClassLoader loader, Class?[] interfaces, InvocationHandler h) 方法创建一个代理对象方法的三个入参分别是 ClassLoader loader用于加载代理对象的 Class 类加载器Class?[] interfaces代理对象需要实现的接口InvocationHandler h代理对象的处理器 static void JDKDynamicProxyTest() {// 被代理的对象1Human human new Human();// 获取代理对象只能强转成传入的接口之一CanWalk humanProxy (CanWalk) Proxy.newProxyInstance(Human.class.getClassLoader(), // 指定类加载器Human.class.getInterfaces(), // 指定接口可以替换为 new Class[]{CanWalk.class, CanEat.class}new MyInvocationHandler(human) // 自定义的 InvocationHandler);// 调用代理对象的方法转发给InvocationHandler.invoke(...)humanProxy.walk();// 被代理的对象2Fish fish new Fish();CanEat fishProxy (CanEat) Proxy.newProxyInstance(Fish.class.getClassLoader(),new Class[]{CanEat.class},new MyInvocationHandler(fish));fishProxy.eat();}执行结果 JDK dynamic proxy: write to log walk with human feet JDK dynamic proxy: write to log eat with fish mouth任何其它类即使没有实现上述两个接口也能用这个动态代理类记录日志CGLIB动态代理 JDK 动态代理的目标对象必须是一个接口CGLIB 动态代理则是基于类代理cglib 针对类建立代理实例创建代理对象时不必创建被代理对象新生成的代理对象的 Class 对象会继承被代理的类重写父类被代理的类的所有非 final 的 public 方法将其改为调用 Callback 的方法因为被代理类需要被继承所以 final 修饰的类不能使用 cglib class MyInterceptor implements MethodInterceptor {/*** param o 代理类对象* param method 调用的原生方法* param objects 方法参数* param methodProxy 代理方法* throws Throwable*/Overridepublic Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {System.out.println(cglib dynamic proxy: write to log);methodProxy.invokeSuper(o, objects);return null;} }static void CglibDynamicProxyTest() {// 创建代理类Enhancer enhancer new Enhancer();enhancer.setSuperclass(Human.class); // 设置被代理的类无需创建被代理的对象enhancer.setCallback(new MyInterceptor()); // 方法增强Human humanProxy (Human) enhancer.create();// 调用增强方法humanProxy.eat();humanProxy.walk();}Spring MVC 1 作用 Spring MVC 是一种基于 Java 的实现 MVCModel - View - Controller 设计模式的请求驱动类型的轻量级 WEB 框架Spring MVC 底层是 Servlet对 Servlet 进行了深层次的封装 2 Spring MVC 执行流程 客户端浏览器发送请求直接请求到 DispatcherServletDispatcherServlet 根据请求信息调用 HandlerMapping解析请求对应的 HandlerExecutionChain包括 Handler 对象以及对应的拦截器解析到对应的 Handler也就是 Controller后开始由 HandlerAdapter 适配器处理HandlerAdapter 会根据 Handler 来调用真正的处理器开处理请求并处理相应的业务逻辑处理器处理完业务后会返回一个 ModelAndView 对象Model 是返回的数据对象View 是逻辑上的视图DispatcherServlet 根据返回的 ModelAndView选择合适的 ViewResolver 根据逻辑 View 查找实际的 ViewDispaterServlet 进行视图渲染把渲染结果返回给请求者浏览器 Spring Boot 1 SpringBootApplication 做了哪些事 SpringBootApplication Configuration EnableAutoConfiguration ComponentScan EnableAutoConfiguration启用 SpringBoot 的自动配置机制ComponentScan 扫描被 Component (Service,Controller) 注解的 bean注解默认会扫描该类所在的包下所有的类Configuration允许在 Spring 上下文中注册额外的 bean 或导入其他配置类 2 Spring Boot 自动装配原理 自动装配可以简单理解为通过注解或者一些简单的配置就能在 Spring Boot 的帮助下实现某块功能 SpringBootApplication - EnableAutoConfiguration - AutoConfigurationImportSelectorAutoConfigurationImportSelector 实现了 ImportSelector 接口中的 selectImports 方法该方法主要用于获取所有符合条件的类的全限定类名返回 String 数组一系列的 “xxxAutoConfiguration”这些类需要被加载到 IoC 容器中 private static final String[] NO_IMPORTS new String[0];public String[] selectImports(AnnotationMetadata annotationMetadata) {// 1.判断自动装配开关是否打开if (!this.isEnabled(annotationMetadata)) {return NO_IMPORTS;} else {//2.获取所有需要装配的beanAutoConfigurationMetadata autoConfigurationMetadata AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry this.getAutoConfigurationEntry(autoConfigurationMetadata, annotationMetadata); // 下图详细说明return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());} }下图中的红色字体“自动配置类名”即为 xxxAutoConfiguration 类 所有 Spring Boot Starter 下的 META-INF/spring.factories 都会被读取到。XXXAutoConfiguration 类的作用就是按需加载组件 启动应用时不同的 Stater 的 spring.factories 的配置很多每次启动不会全部加载。只有自动配置类或其中的方法上的 ConditionalOnXXX 中的所有条件都满足才会生效 Configuration // 检查相关的类是否存在存在才会加载 ConditionalOnClass({EnableAspectJAutoProxy.class, Aspect.class, Advice.class, AnnotatedElement.class}) ConditionalOnProperty(prefix spring.aop, name {auto}, havingValue true, matchIfMissing true) public class AopAutoConfiguration {// ...ConfigurationEnableAspectJAutoProxy(proxyTargetClass true)ConditionalOnProperty(prefix spring.aop, name {proxy-target-class}, havingValue true, matchIfMissing true)public static class CglibAutoProxyConfiguration {public CglibAutoProxyConfiguration() {}}// ... }Spring Cloud 1 CAP 在一个分布式系统中Consistency一致性、 Availability可用性、Partition tolerance分区容错性三者不可同时获得 C假设在 T 时刻写入了一个值那么在 T 之后的读取一定要能读到这个最新的值所有节点在同一时间的数据完全一致越多节点数据同步越耗时A无论系统发生任何故障都仍然能对外提供服务服务一直可用而且是正常响应时间P网络分区容错性高可用性一个节点挂掉不影响其它的节点。由于当前的网络硬件肯定会出现延迟丢包等问题所以分区容忍性是必须需要实现的只能在一致性和可用性之间进行权衡
http://www.zqtcl.cn/news/725011/

相关文章:

  • 租用网站服务器价格清远医院网站建设方案
  • 房地产网站建设方案书福田所有车型
  • 网站功能描述高清视频网络服务器免费
  • 天台做网站微博推广效果怎么样
  • 苏州专门网站网站站长统计怎么做
  • 社交网站开发注意事项call_user_func_array() wordpress
  • 泉州企业免费建站个人网站设计与开发
  • 网站建设流程书籍互联网行业黑话
  • 山亭 网站建设wordpress 添加头像
  • 龙南县建设局网站新手如何做网络推广
  • 网站开发建设赚钱吗巩义旅游网站建设公司
  • 网站建设代码介绍网站顶部导航代码
  • 帮别人做网站需要什么能力sem专员
  • 无锡网站建设 app推广软件
  • 免费入驻的外贸网站网站建设怎么打开
  • 怎么做中英文网站网站建设费做什么
  • 信阳网站建设汉狮怎么样做曖視頻网站
  • 做电影电视剧网站推广移动应用开发是什么意思
  • 网站排名优化策划中山搜索引擎优化
  • 网站建设培训证书平台型网站建设预算表
  • 网站建设后压缩代码网站如何做进一步优化
  • 大型旅游网站源码 织梦襄阳网站建设楚翼网络
  • 快速搭建网站服务器做历史卷子的网站
  • 淘口令微信网站怎么做通化seo招聘
  • 帮人做传销网站违法吗深圳也放开了
  • 发布程序后网站有很多促销策略
  • 网页网站项目综合网站建设合同.doc
  • 网站建设公司黄页企业vi系统设计公司
  • 建设局网站新闻昆明个人网站建设平台
  • 清远市建设工程交易中心网站网站打开慢什么原因呢