Spring注解驱动开发--AOP底层原理
Spring注解驱动开发–AOP底层原理
21. AOP-AOP功能测试
AOP:【动态代理】
指在程序运行期间动态的将某段代码切入到指定方法指定位置进行运行的编程方式;
1、导入aop模块:Spring AOP,(Spring-aspects)
2、定义一个业务逻辑类(MathCalculator):在业务逻辑运行的时候将日志进行打印(方法之前、方法运行结束、方法出现异常、xxx)
3、定义一个日志切面类(LogAspects);切面类里面的方法需要动态感知MathCalculator,div运行到哪里然后哪里就执行。
通知方法:
前置通知(@Before):logStart:在目标方法(div)运行之前运行
后置通知(@After):logENd:在目标方法(div)运行结束之后运行
返回通知(@AfterReturning):logReturn:在目标方法(div)正常返回之后运行
异常通知(@AfterThrowing):logException:在目标方法(div)出现异常以后运行
环绕通知(@Around):动态代理:手动推进目标方法运行(joinPoint.procces())
4、给切面类的目标方法标注何时何地地运行(通知注释)
5、将切面类和业务逻辑类(目标方法所在类)都加入到容器中
6、必须告诉Spring哪个类是切面类(给切面类上加一个注解:@Aspect)
【7】、给配置类中加 @EnableAspectJAutoProxy 【开启基于注解的aop模式】
在Spring中很多的 @EnableXXX;
三步:
1)、将业务逻辑组件和切面类都加入到容器中;告诉Spring哪个是切面类(@Aspect)
2)、在切面类上的每一个通知方法上标注通知注解,告诉Spring何时何地运行(切入点表达式)
3)、开启基于注解的aop模式:@EnableAspectJAutoProxy
第一步、导入aop模块
<dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>4.3.12.RELEASE</version></dependency>
第二步、定义一个业务逻辑类(MathCalculator)
public class MathCalculator {public int div(int i,int j){System.out.println("MathCalculator...div...");return i/j;}}
第三步、定义一个日志切面类(LogAspects)
/*** 切面类** @Aspect:告诉Spring当前类是一个切面类*/
@Aspect //告诉Spring当前类是一个切面类
public class LogAspects {//抽取公共的切入点表达式//1.本类引用//2.其他的切面引用@Pointcut("execution(public int com.xjz.aop.MathCalculator.*(..))")public void pointCut(){};//@Before在目标方法之前切入;切入点表达式(指定在哪个方法切入)@Before("pointCut()")public void logStart(JoinPoint joinPoint){Object[] args = joinPoint.getArgs();System.out.println(""+joinPoint.getSignature().getName()+"运行。。。@Before:参数列表是:{"+ Arrays.asList(args) +"}");}@After("com.xjz.aop.LogAspects.pointCut()")public void logEnd(JoinPoint joinPoint){System.out.println(""+joinPoint.getSignature().getName()+"结束。。。@After");}//JoinPoint一定要出现在参数表的第一位@AfterReturning(value = "pointCut()",returning = "result")public void logReturn(JoinPoint joinPoint,Object result){System.out.println(""+joinPoint.getSignature().getName()+"正常返回。。。@AfterReturning:运行结果:{"+result+"}");}@AfterThrowing(value = "pointCut()",throwing = "exception")public void logException(JoinPoint joinPoint,Exception exception){System.out.println(""+joinPoint.getSignature().getName()+"异常。。。@AfterThrowing:异常信息:{"+exception+"}");}
}
第四步、将切面类和业务逻辑类(目标方法所在类)都加入到容器中
@EnableAspectJAutoProxy //开启基于注解的aop模式
@Configuration
public class MyConfigOfAOP {//业务逻辑类加入到容器中@Beanpublic MathCalculator calculator(){return new MathCalculator();}//切面类加入到容器中@Beanpublic LogAspects logAspects(){return new LogAspects();}}
第五步、测试
public class IOCTest_AOP {@Testpublic void test01(){AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfigOfAOP.class);//1.不要自己创建对象
// MathCalculator mathCalculator = new MathCalculator();
// mathCalculator.div(1,1);MathCalculator mathCalculator = applicationContext.getBean(MathCalculator.class);mathCalculator.div(1,1);applicationContext.close();}
}
第六步、运行结果
- 正常返回
- 异常报错
22. AOP原理
AOP:【动态代理】指在程序运行期间动态的将某段代码切入到指定方法指定位置进行运行的编程方式;
1、导入aop模块:Spring AOP,(Spring-aspects)
2、定义一个业务逻辑类(MathCalculator):在业务逻辑运行的时候将日志进行打印(方法之前、方法运行结束、方法出现异常、xxx)
3、定义一个日志切面类(LogAspects);切面类里面的方法需要动态感知MathCalculator,div运行到哪里然后哪里就执行。通知方法:前置通知(@Before):logStart:在目标方法(div)运行之前运行后置通知(@After):logENd:在目标方法(div)运行结束之后运行返回通知(@AfterReturning):logReturn:在目标方法(div)正常返回之后运行异常通知(@AfterThrowing):logException:在目标方法(div)出现异常以后运行环绕通知(@Around):动态代理:手动推进目标方法运行(joinPoint.procces())
4、给切面类的目标方法标注何时何地地运行(通知注释)
5、将切面类和业务逻辑类(目标方法所在类)都加入到容器中
6、必须告诉Spring哪个类是切面类(给切面类上加一个注解:@Aspect)
【7】、给配置类中加 @EnableAspectJAutoProxy 【开启基于注解的aop模式】在Spring中很多的 @EnableXXX;
三步:1)、将业务逻辑组件和切面类都加入到容器中;告诉Spring哪个是切面类(@Aspect)2)、在切面类上的每一个通知方法上标注通知注解,告诉Spring何时何地运行(切入点表达式)3)、开启基于注解的aop模式:@EnableAspectJAutoProxy
AOP原理:【看给容器中注册了什么组件,这个组件什么时候工作,这个组件的功能是什么?】@EnableAspectJAutoProxj;1、@EnableAspectJAutoProxj是什么?@Import(AspectJAutoProxyRegistrar.class):给容器中导入AspectJAutoProxyRegistrar利用AspectJAutoProxyRegistrar自定义给容器中注册bean;BeanDefinetioninternalAutoProxyCreator = AnnotationAwareAspectJAutoProxyCreator;给容器中注册一个AnnotationAwareAspectJAutoProxyCreator;2、AnnotationAwareAspectJAutoProxyCreatorAnnotationAwareAspectJAutoProxyCreator->AspectJAwareAdvisorAutoProxyCreator->AbstractAdvisorAutoProxyCreator->AbstractAutoProxyCreatorimplements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware关注后置处理器(在bean初始化完成前后做事情)、自动装配BeanFactoryAwareAbstractAutoProxyCreator.setBeanFactory()AbstractAutoProxyCreator.有后置处理器的逻辑;AbstractAdvisorAutoProxyCreator.setBeanFactory()-->initBeanFactory()AnnotationAwareAspectJAutoProxyCreator.initBeanFactory()流程:1)、传入配置类,创建ioc容器2)、注册配置类,调用refresh()刷新容器;3)、registerBeanPostProcessors(beanFactory);注册bean的后置处理器来方便拦截bean的创建;1)、先获取ioc容器已经定义了的需要创建对象的所有BeanPostProcessor2)、给容器中加别的BeanPostProcessor3)、优先注册实现了呢PriorityOrdered接口的BeanPostProcessor;4)、再给容器中注册实现了Ordered接口和BeanPostProcessor;5)、注册没实现优先级接口的BeanPostProcessor6)、注册BeanPostProcessor,实际上就是创建BeanPostProcessor对象,保存在容器中;创建internalAutoProxyCreator的BeanPostProcessor【AnnotationAwareAspectJAutoProxy】1)、创建Bean的实例;2)、populateBean:给bean的各种属性赋值3)、initializeBean:初始化bean;1)、invokeAwareMethods():处理Aware接口的方法回调2)、applyBeanPostProcessorBeforeInitialization():应用后置处理器的postProcessBefore3)、invokeInitMethods():执行自定义的初始化方法4)、applyBeanPostProcessorAfterInitialization():执行后置处理器的postProcessAfterIn4)、BeanPostProcessor(AnnotationAwareAspectJAutoProxyCreator)创建成功:--》aspectJAdvis7)、把BeanPostProcessor注册到BeanFactory中:beanFactory.addBeanPostProcessor(postProcessor);
========以上是创建和注册AnnotationAwareAspectJAutoProxyCreator的过程===========AnnotationAwareAspectJAutoProxyCreator =》 InstantiationAwareBeanPostProcessor4)、finishBeanFactoryInitialization(beanFactory);完成BeanFactory初始化工作;创建剩下的单实例Bean1)、遍历获取容器中所有的Bean,依次创建对象getBean(beanName);getBean->doGetBean()->getSingleton()->2)、创建bean【AnnotationAwareAspectJAutoProxyCreator在所有bean创建之前会有一个拦截,InstantiationAwareBeanPostP1)、先从缓存中获取当前bean,如果能获取到,说明bean是之前被创建过的,直接使用,否则再创建;只要创建好的Bean都会被缓存起来2)、createBean();创建bean;AnnotationAwareAspectJAutoProxyCreator会在任何bean创建之前先尝试返回bean的实例【BeanPostProcessor是在Bean对象创建完成初始化前后调用的】【InstantiationAwareBeanPostProcessor是在创建Bean实例之前先尝试用后置处理器返回对象的】1)、resolveBeforeInstantiation(beanName,mbdToUse);解析BeforeInstantiation希望后置处理器在此前能返回一个代理对象;如果能返回代理对象就使用,如果不能就继续1)、后置处理器先尝试返回对象:bean = applyBeanPostProcessorsBeforeInstantiation();拿到所有后置处理器,如果是InstantiationAwareBeanPostProcessor;就执行postProcessBeforeInstantiationif (bean != null) {bean = applyBeanPostProcessorsBeforeInstantiation(bean,beanName)}2)、doCreateBean(beanName, mbdToUse, args);真正的去创建一个bean实例;和3.6流程一样3)、AnnotationAwareAspectJAutoProxyCreator【InstantiationAwareBeanPostProcessor】的使用:1)、每一个bean创建之前,调用postProcessBeforeInstantiation();关心MathCalculator和LogAspect的创建1)、判断当前bean是否在advisedBeans中(保存了所有需要增强bean)2)、判断当前bean是否是基础类型的Advice、Pointcut、Advisor、AOPInfrastructureBean.或者是否是切面(@Aspect)3)、是否需要跳过1)、获取候选的增强器(切面里面的通知方法)【List<Advisor、candidateAdvisors】每一个封装的通知方法的增强器是InstantiationModelAwarePointcutAdvisor;判断每一个增强器是否是AspectJPointcutAdvisor类型的;返回true2)、永远返回false2)、创建对象postProcessAfterInitialization;return wrapIfNecessary(bean, beanName,cacheKey);//包装如果需要的情况下1)、获取当前bean的所有增强器(通知方法)1、找到候选的所有的增强器(找哪些通知方法是需要切入当前bean方法的)2、获取到能在bean使用的增强器。3、给增强器排序2)、保存当前bean在advisedBeans中:3)、如果当前bean需要增强,创建当前bean的代理对象;1)、获取所有增强器(通知方法)2)、保存到proxyFactory3)、创建代理对象;Spring自动决定JdkDynamicAopProxy(config);jdk动态代理ObjenesisCglibAopProxy(config);cglib的动态代理4)、给容器中返回当前组件使用cglib增强了的代理对象;5)、以后容器中获取到的就是这个组件的代理对象,执行目标方法的时候,代理对象就会执行通知方法的流程3)、目标方法执行:容器中保存了组件的代理对象(cglib增强后的对象),这个对象里面保存了详细信息(比如增强器,目标对象,xxx);1)、CglibAopProxy.intercept();拦截目标方法的执行2)、根据ProxyFactory对象获取将要执行的目标方法拦截器链;List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvi1)、List<Object> interceptorList保存所有拦截器一个默认的ExposeInvocationinterceptor 和4个增强器;2)、遍历所有的增强器,将其转为Interceptorregistry.getInterceptors(advisor);3)、 将增强器转为List<MethodInterceptor>数组;如果是MethodInterceptor,直接加入到集合中如果不是,使用AdvisorAdapter将增强器转为MethodINterceptor;转换完成返回MethodInterceptor数据;3)、如果没有拦截器链,直接执行目标方法;拦截器链(每一个通知方法又被包装为方法拦截器)4)、如果有拦截器链,把需要执行的目标对象、目标方法,拦截器链等信息传入创建一个CglibMethodInvocation对象;并调用 Object retVal = mi.proceed();5)、拦截器链的触发过程1)、如果没有拦截器执行目标方法,或者拦截器的索引和拦截器数据-1大小一样(指定到了最后一个拦截器)执行目标方法;2)、链式获取每一个拦截器,拦截器执行invoke方法,每一个拦截器等待下一个拦截器执行完成返回以后再来执行;拦截器链的机制,保证通知方法与目标方法的执行顺序总结:1)、@EnableAspectJAutoProxy 开启AOP功能2)、@EnableAspectJAutoProxy 会给容器中注册一个组件 AnnotationAwareAspectJAutoProxyCreator3)、AnnotationAwareAspectJAutoProxyCreator是一个后置处理器;4)、容器的创建流程:1)、registerBeanPostProcessors() 注册后置处理器;创建 AnnotationAwareAspectJAutoProxyCreator对象2)、finishBeanFactoryInitialization()初始化剩下的单实例bean1)、创建业务逻辑组件和切面组件2)、AnnotationAwareAspectJAutoProxyCreator拦截组件的创建过程3)、组件创建完之后,判断组件是否需要增强是:切面的通知方法,包装成增强器(Advisor);给业务逻辑组件创建一个代理对象(cglib);5)、执行目标方法:1)、代理对象执行目标方法2)、CglibAopProxy.intercept();1)、得到目标方法的拦截器链(增强器包装成拦截器MethodInterceptor)2)、利用拦截器的链式机制,依次进入每一个拦截器进行执行;3)、效果:(Spring4):正常执行,前置通知-》目标方法-》后置通知-》返回通知出现异常,前置通知-》目标方法-》后置通知-》异常通知(Spring5):正常执行,前置通知-》目标方法-》返回通知-》后置通知出现异常,前置通知-》目标方法-》异常通知-》后置通知
**注意:**一定要跟着雷老师进源码,不然很快就会忘掉的!!
相关文章:
Spring注解驱动开发--AOP底层原理
Spring注解驱动开发–AOP底层原理 21. AOP-AOP功能测试 AOP:【动态代理】 指在程序运行期间动态的将某段代码切入到指定方法指定位置进行运行的编程方式; 1、导入aop模块:Spring AOP,(Spring-aspects) 2、定义一个业务逻辑类(Ma…...
对象的动态创建和销毁以及对象的复制,赋值
🐶博主主页:ᰔᩚ. 一怀明月ꦿ ❤️🔥专栏系列:线性代数,C初学者入门训练,题解C,C的使用文章,「初学」C 🔥座右铭:“不要等到什么都没有了,才…...
JVM调优,调的是什么?目的是什么?
文章目录前言一、jvm是如何运行代码的?二、jvm的内存模型1 整体内存模型结构图2 堆中的年代区域划分3 对象在内存模型中是如何流转的?4 什么是FULL GC,STW? 为什么会发生FULL GC?5 要调优,首先要知道有哪些垃圾收集器及哪些算法6 调优不是盲目的,要有依据,几款内…...
docker部署zabbix监控
docker部署zabbix监控 1、环境说明 公有云ubuntu22.04 系统->部署docker环境zabbix-server 6.4 2、准备docker环境 更新apt以及安装一些必要的系统工具 sudo apt-get update sudo apt-get -y install apt-transport-https ca-certificates curl software-properties-co…...
C语言刷题(6)(猜名次)——“C”
各位CSDN的uu们你们好呀,今天,小雅兰还是在复习噢,今天来给大家介绍一个有意思的题目 题目名称: 猜名次 题目内容: 5位运动员参加了10米台跳水比赛,有人让他们预测比赛结果: A选…...
两年外包生涯,感觉自己废了一半....
先说一下自己的情况。大专生,17年通过校招进入湖南某软件公司,干了接近2年的点点点,今年年上旬,感觉自己不能够在这样下去了,长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了五年的功能测试…...
【python】喜欢XJJ?这不得来一波大采集?
前言 大家早好、午好、晚好吖 ❤ ~欢迎光临本文章 俗话说的好:技能学了~就要用在自己喜欢得东西上!! 这我不得听个话~我喜欢小姐姐,跳舞的小姐姐 这不得用python把小姐姐舞采集下来~嘿嘿嘿 完整源码、素材皆可点击文章下方名片…...
公司测试员用例写得乱七八糟,测试总监制定了这份《测试用例编写规范》
统一测试用例编写的规范,为测试设计人员提供测试用例编写的指导,提高编写的测试用例的可读性,可执行性、合理性。为测试执行人员更好执行测试,提高测试效率,最终提高公司整个产品的质量。 一、范围 适用于集成测试用…...
LeetCode 热题 HOT 100【题型归类汇总,助力刷题】
介绍 对于算法题,按题型类别刷题才会更有成效,因此我这里在网上搜索并参考了下 “🔥 LeetCode 热题 HOT 100” 的题型归类,并在其基础上做了一定的完善,希望能够记录自己的刷题历程,有所收获!具…...
【Java进阶篇】—— File类与IO流
一、File类的使用 1.1 概述 File 类以及本章中的各种流都定义在 java.io 包下 一个File对象代表硬盘或网络中可能存在的一个文件或文件夹(文件目录) File 能新建、删除、重命名 文件和目录,但 File不能访问文件内容本身。如果我们想要访问…...
Mysql 竟然还有这么多不为人知的查询优化技巧,还不看看?
前言 Mysql 我随手造200W条数据,给你们讲讲分页优化 MySql 索引失效、回表解析 今天再聊聊一些我想分享的查询优化相关点。 正文 准备模拟数据。 首先是一张 test_orde 表: CREATE TABLE test_order (id INT(11) NOT NULL AUTO_INCREMENT,p_sn VARCHA…...
MATLAB算法实战应用案例精讲-【智能优化算法】海洋捕食者算法(MPA) (附MATLAB和python代码实现)
目录 前言 知识储备 Lvy 飞行 布朗运动 算法原理 算法思想 数学模型...
Spring @Profile
1. Overview In this tutorial, we’ll focus on introducing Profiles in Spring. Profiles are a core feature of the framework — allowing us to map our beans to different profiles — for example, dev, test, and prod. We can then activate different profiles…...
Vue3电商项目实战-个人中心模块4【09-订单管理-列表渲染、10-订单管理-条件查询】
文章目录09-订单管理-列表渲染10-订单管理-条件查询09-订单管理-列表渲染 目的:完成订单列表默认渲染。 大致步骤: 定义API接口函数抽取单条订单组件获取数据进行渲染 落的代码: 1.获取订单列表API借口 /*** 查询订单列表* param {Number…...
【十二天学java】day01-Java基础语法
day01 - Java基础语法 1. 人机交互 1.1 什么是cmd? 就是在windows操作系统中,利用命令行的方式去操作计算机。 我们可以利用cmd命令去操作计算机,比如:打开文件,打开文件夹,创建文件夹等。 1.2 如何打…...
【面试题】闭包是什么?this 到底指向谁?
一通百通,其实函数执行上下文、作用域链、闭包、this、箭头函数是相互关联的,他们的特性并不是孤立的,而是相通的。因为内部函数可以访问外层函数的变量,所以才有了闭包的现象。箭头函数内没有 this 和 arguments,所以…...
汽车4S店业务管理软件
一、产品简介 它主要提供给汽车4S商店,用于管理各种业务,如汽车销售、售后服务、配件、精品和保险。整个系统以客户为中心,以财务为基础,覆盖4S商店的每一个业务环节,不仅可以提高服务效率和客户满意度,…...
基于 pytorch 的手写 transformer + tokenizer
先放出 transformer 的整体结构图,以便复习,接下来就一个模块一个模块的实现它。 1. Embedding Embedding 部分主要由两部分组成,即 Input Embedding 和 Positional Encoding,位置编码记录了每一个词出现的位置。通过加入位置编码可以提高模型的准确率,因为同一个词出现在…...
算法小抄6-二分查找
二分查找,又名折半查找,其搜索过程如下: 从数组中间的元素开始,如果元素刚好是要查找的元素,则搜索过程结束如果搜索元素大于或小于中间元素,则排除掉不符合条件的那一半元素,在剩下的数组中进行查找由于每次需要排除掉一半不符合要求的元素,这需要数组是已经排好序的或者是有…...
大学四年..就混了毕业证的我,出社会深感无力..辞去工作,从头开始
时间如白驹过隙,一恍就到了2023年,今天最于我来说是一个值得纪念的日子,因为我收获了今年的第一个offer背景18年毕业,二本。大学四年,也就将就混了毕业证和学位证。毕业后,并未想过留在湖南,就回…...
C语言数据结构初阶(6)----链表常见OJ题
CSDN的uu们,大家好!编程能力的提高不仅需要学习新的知识,还需要大量的练习。所以,C语言数据结构初阶的第六讲邀请uu们一起来看看链表的常见oj题目。移除链表元素原题链接:203. 移除链表元素 - 力扣(Leetcod…...
关键字 const
目录 一、符号常量与常变量 二、const的用法 2.1 const常用方法 2.2 const用于指针 2.2.1 p指针所指的对象值不能改变,但是p指针的指向可以改变 2.2.2 常指针p的指向不能改变,但是所指的对象的值可以改变 2.2.3 p所指对象的指向以及对象的值都不可…...
MybatisPlus------MyBatisX插件:快速生成代码以及快速生成CRUD(十二)
MybatisPlus------MyBatisX插件(十二) MyBatisX插件是IDEA插件,如果想要使用它,那么首先需要在IDEA中进行安装。 安装插件 搜索"MyBatisX",点击Install,之后重启IDEA即可。 插件基本用途&…...
Leetcode138. 复制带随机指针的链表
复制带随机指针的链表 第一步 拷贝节点链接在原节点的后面 第二步拷贝原节点的random , 拷贝节点的 random 在原节点 random 的 next 第三步 将拷贝的节点尾插到一个新链表 ,并且将原链表恢复 从前往后遍历链表 ,将原链表的每个节点进行复制,并l链接到原…...
python并发编程多线程
在传统操作系统中,每个进程有一个地址空间,而且默认就有一个控制线程 线程顾名思义,就是一条流水线工作的过程,一条流水线必须属于一个车间,一个车间的工作过程是一个进程 车间负责把资源整合到一起,是一个…...
使用Maven实现Servlet程序
创建Maven项目我们打开idea的新建项目,选中里面Maven即可,如下图:创建完成之后,会看到这样的目录结构其中,main目录存放业务代码,其中的java目录存放的就是java代码,而resources目录存放是程序中依赖的文件,比如:图片,视频等.然后是 test目录,test目录存放的是测试代码.最后一个…...
百度的文心一言 ,没有想像中那么差
robin 的演示 我们用 robin 的演示例子来对比一下 文心一言和 ChatGPT 的真实表现(毕竟发布会上是录的)。 注意,我使用的 GPT 版本是 4.0 文学创作 1 三体的作者是哪里人? 文心一言: ChatGPT: 嗯&a…...
文心一言发布的个人看法
文心一言发布宣传视频按照发布会上说的,文心一言并非属于百度赶工抄袭Chat-GPT的作品,而是十几年一直布局AI产业厚积薄发的成果,百度在芯片,机器学习,自然语言处理,知识图谱等方面均有相对深厚的积累。 国…...
【C5】111
文章目录bmc_wtd:syscpld.c中wd_en和wd_kick节点对应寄存器,crontab,FUNCNAMEAST2500/2600 WDT切换主备:BMC用WDT2作为主备切换的watchdog控制器AC后读取:bmc处于主primary flash(设完后:实际主…...
静态成员,友元函数
🐶博主主页:ᰔᩚ. 一怀明月ꦿ ❤️🔥专栏系列:线性代数,C初学者入门训练,题解C,C的使用文章,「初学」C 🔥座右铭:“不要等到什么都没有了,才下…...
帮别人做网站自己为什么会被抓/百度竞价推广收费
目录 1.简介 2. WebMvcConfigurer接口 常用的方法 2.1 addInterceptors:拦截器 2.2 addViewControllers:页面跳转 2.3 addResourceHandlers:静态资源 2.4 configureDefaultServletHandling:默认静态资源处理器 2.5 configu…...
微网站建设资讯/seo手机关键词网址
base64的好处是什么?今天在跟小伙伴讨论这个问题,要是全站用Php把图片转为base64行不行?1. 提升性能: 网页上的每一个图片,都是需要消耗一个 http 请求下载而来的, 图片的下载始终都要向服务器发出请求,要是图片的下载…...
有做不锈钢工程的网站/网络营销热点事件案例分析
今天简单写了一个jq版购物车计算金额总和的例子,如图: 整体页面代码如下: <!DOCTYPE html> <html><head><meta charset"{CHARSET}"><title></title><script type"text/javascript&quo…...
做网站收入怎样/阿里域名购买网站
人说伟大的旅程都是从第一篇博文开始的! 今天我也在博客园属于我自己的博客上写下了这些文字,并要求自己持续更新,希望籍此鞭策自己不断前行… 又逢一年一度的又十一, 由于闲得无聊, 打开了QQ空间的私密日志ÿ…...
重庆网站建设红旗河沟/超级外链工具有用吗
USE masterGO sp_Configure ALLOW UPDATES, 1 /* 允许直接更新系统表 */RECONFIGURE WITH OVERRIDE /* 更新对当前配置选项值的更改 */GO -- 设置“myTestDB”为“紧急模式”。UPDATE sysdatabases SET status 32768 WHERE name bfxkGO -- 重置 ALLOW UPDATES 为…...
做性事的视频网站名字/论坛如何做seo
特别要注意配置好/etc/profile后,将配置加入/root/.bashrc中;否则,配置的环境变量不会在root账户下生效 在nodejs官网上下载nodejs源码node-v5.1.0-linux-x64.tar.gz,到/opt目录下;进入/opt目录,输入命令&…...