1.接口 Class<?> resourceClass

2.获取builder

BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(resourceClass);

3.获取接口对应的动态代理class

Class<?> targetProxyClass = Proxy.getProxyClass(XXX.class.getClassLoader(), new Class[]{resourceClass});

4.targetProxyClass构造参数类型 InvocationHandler,通过builder设置

builder.addConstructorArgValue(Proxy.getInvocationHandler(xxxProxyBean) 或者 new InvocationHandler(){...});

 AbstractBeanDefinition beanDefinition = builder.getBeanDefinition();

beanDefinition.setBeanClass(targetProxyClass);

registry.registerBeanDefinition("beanName", beanDefinition);

5.记录一下自己曾经写的一个例子

5.1 抽象类ProxyFactoryBean

package com.hjzgg.apigateway.soa.proxy;

import com.hjzgg.apigateway.soa.exceptions.SoaException;
import com.hjzgg.apigateway.soa.proxy.consumer.ConsumerProxyFactoryBean;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.util.ClassUtils; import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream; /**
* Created by hujunzheng on 2017/7/7.
*/
public abstract class ProxyFactoryBean implements FactoryBean { protected Class<?> selfDynamicProxyClass;//代理类
protected Class<?> resourceClass;//接口类
protected String version;//dubbo 版本
protected String group;//dubbo 分组
protected Object proxy;//代理对象
protected Method createProxyMethod; public ProxyFactoryBean(Class<?> selfDynamicProxyClass, Class<?> resourceClass, String version, String group) throws SoaException {
if (Objects.isNull(selfDynamicProxyClass)) {
throw new SoaException("selfDynamicProxyClass 动态代理类不能为null");
}
try {
this.createProxyMethod = Stream.of(selfDynamicProxyClass.getMethods())
.filter(method -> Modifier.isStatic(method.getModifiers())
&& Modifier.isPublic(method.getModifiers())
&& !Modifier.isAbstract(method.getModifiers())
&& method.getParameters().length == 2
&& method.getParameters()[0].getType().equals(ProxyFactoryBean.class)
&& method.getParameters()[1].getType().equals(Class.class)
&& !method.getReturnType().equals(void.class))
.collect(Collectors.toList())
.get(0);
} catch (Exception e) {
throw new SoaException("500", String.format("%s %s %s和%s %s, %s %s"
, ClassUtils.getQualifiedName(selfDynamicProxyClass)
, " 没有参数类型是 "
, ClassUtils.getQualifiedName(ConsumerProxyFactoryBean.class)
, ClassUtils.getQualifiedName(Class.class)
, " 的、公共的、非抽象的、返回值非void的方法"
, "请将你的动态代理类继承"
, ClassUtils.getQualifiedName(DynamicProxyAdapter.class)
), e);
} this.selfDynamicProxyClass = selfDynamicProxyClass;
this.resourceClass = resourceClass;
this.version = version;
this.group = group;
} protected Object newInstance() throws SoaException {
if(this.isSingleton() && this.proxy != null) {
return proxy;
}
synchronized (this) {
Object target;
try {
target = this.createProxyMethod.invoke(null,this, selfDynamicProxyClass);
} catch (Exception e) {
throw new SoaException("500", String.format("%s %s %s"
, ClassUtils.getQualifiedName(selfDynamicProxyClass)
, createProxyMethod.getName()
, "创建代理类异常")
, e);
}
if(proxy == null) {
proxy = target;
}
return target;
}
} public Class<?> getSelfDynamicProxyClass() {
return selfDynamicProxyClass;
} public void setSelfDynamicProxyClass(Class<?> selfDynamicProxyClass) {
this.selfDynamicProxyClass = selfDynamicProxyClass;
} public Class<?> getResourceClass() {
return resourceClass;
} public void setResourceClass(Class<?> resourceClass) {
this.resourceClass = resourceClass;
} public String getVersion() {
return version;
} public void setVersion(String version) {
this.version = version;
} public String getGroup() {
return group;
} public void setGroup(String group) {
this.group = group;
}
}

5.2 ProxyFactoryBean具体实现类ProviderProxyFactoryBean

package com.hjzgg.apigateway.soa.proxy.provider;

import com.hjzgg.apigateway.soa.exceptions.SoaException;
import com.hjzgg.apigateway.soa.proxy.ProxyFactoryBean;
import org.springframework.aop.SpringProxy;
import org.springframework.aop.TargetClassAware; import java.lang.reflect.Method;
import java.lang.reflect.Proxy; /**
* @author hujunzheng
* @create 2018-02-18 下午3:01
**/
public class ProviderProxyFactoryBean extends ProxyFactoryBean {
public ProviderProxyFactoryBean(Class<?> selfDynamicProxyClass, Class<?> resourceClass, String version, String group) throws SoaException {
super(selfDynamicProxyClass, resourceClass, version, group);
} @Override
public Object getObject() throws Exception {
return this.newInstance();
} @Override
public Class<?> getObjectType() {
return resourceClass;
} @Override
public boolean isSingleton() {
return true;
} public static Class<?> getProxyClass(Class<?> resourceClass) {
/**
* @see com.hjzgg.apigateway.dubbo.configure.SelfDubboAnnotationBean#postProcessAfterInitialization(Object, String)
* @see org.springframework.aop.support.AopUtils#isAopProxy(Object)
* @see org.springframework.aop.support.AopUtils#getTargetClass(Object)
* @see com.hjzgg.apigateway.soa.proxy.provider.ProviderDynamicProxy#invoke(Object, Method, Object[])
* */
return Proxy.getProxyClass(ProviderProxyFactoryBean.class.getClassLoader(), new Class[]{resourceClass, SpringProxy.class, TargetClassAware.class});
}
}

5.3 动态代理适配器DynamicProxyAdapter

package com.hjzgg.apigateway.soa.proxy;

import com.hjzgg.apigateway.soa.exceptions.SoaException;
import org.springframework.util.ClassUtils; import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; /**
* @author hujunzheng
* @create 2018-02-04 上午12:00
**/
public class DynamicProxyAdapter implements InvocationHandler {
public DynamicProxyAdapter(ProxyFactoryBean factoryBean) {
this.bean = factoryBean;
} protected ProxyFactoryBean bean; @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
throw new SoaException(String.format("%s %s %s", "你应当重写", ClassUtils.getQualifiedName(DynamicProxyAdapter.class), "invoke方法"));
} public static Object createJDKProxy(ProxyFactoryBean factoryBean, Class<?> selfDynamicProxyClass) throws SoaException {
if (!DynamicProxyAdapter.class.equals(selfDynamicProxyClass.getSuperclass())) {
throw new SoaException(String.format("%s %s %s"
, ClassUtils.getQualifiedName(selfDynamicProxyClass)
, "需要继承"
, ClassUtils.getQualifiedName(DynamicProxyAdapter.class)
));
}
Object selfDynamicProxyInstance;
try {
selfDynamicProxyInstance = selfDynamicProxyClass.getConstructor(factoryBean.getClass()).newInstance(factoryBean);
} catch (Exception e) {
throw new SoaException("500", "动态代理类创建失败", e);
}
Object proxy = Proxy.newProxyInstance(selfDynamicProxyClass.getClassLoader(),
new Class[]{factoryBean.getResourceClass()}, (InvocationHandler) selfDynamicProxyInstance);
return proxy;
}
}

5.4 继承DynamicProxyAdapter 实现invoke接口 ProviderDynamicProxy

package com.hjzgg.apigateway.soa.proxy.provider;

import com.hjzgg.apigateway.commons.utils.ContextUtils;
import com.hjzgg.apigateway.soa.annotation.SOAImplements;
import com.hjzgg.apigateway.soa.exceptions.SoaException;
import com.hjzgg.apigateway.soa.proxy.DynamicProxyAdapter;
import com.hjzgg.apigateway.soa.proxy.consumer.ConsumerProxyFactoryBean;
import org.springframework.aop.TargetClassAware;
import org.springframework.util.ClassUtils; import java.lang.reflect.Method;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Stream; public class ProviderDynamicProxy extends DynamicProxyAdapter { private static final ConcurrentHashMap<Class<?>, Object> map = new ConcurrentHashMap<>(); public ProviderDynamicProxy(ProviderProxyFactoryBean factoryBean) {
super(factoryBean);
} @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try {
if (method.equals(TargetClassAware.class.getMethod("getTargetClass", new Class[]{}))) {
return bean.getResourceClass();
}
return method.invoke(this.findRelevantServiceProvider(), args);
} catch (Exception e) {
throw new SoaException("500", String.format("%s %s %s"
, "invoke service proxy object error!"
, ClassUtils.getQualifiedName(this.bean.getResourceClass())
, method.getName()
), e);
}
} private Object findRelevantServiceProvider() throws SoaException {
Class<?> resourceClass = super.bean.getResourceClass(); if (!map.contains(resourceClass)) {
Stream<?> stream = ContextUtils.getBeans(SOAImplements.class)
.stream()
.filter(serviceProvider -> resourceClass.isAssignableFrom(serviceProvider.getClass()));
if (stream.count() > 1) {
throw new SoaException(String.format(
"multiple relevant service provider found with annotation %s and interface is %s"
, ClassUtils.getQualifiedName(SOAImplements.class)
, ClassUtils.getQualifiedName(resourceClass))
);
} if (stream.count() == 1) {
map.put(resourceClass, stream.findFirst().get());
} else {
List<?> objects = ContextUtils.getBeans(SOAImplements.class);
if (objects.size() > 1) {
throw new SoaException(String.format(
"multiple relevant service provider found with annotation %s"
, ClassUtils.getQualifiedName(SOAImplements.class))
);
} if (objects.size() == 1) {
map.put(resourceClass, objects.get(0));
} else {
try {
Object object = ContextUtils.getBean(resourceClass);
map.put(resourceClass, object);
} catch (Exception e) {
throw new SoaException("500", String.format(
"find relevant service provider with interface %s error"
, ClassUtils.getQualifiedName(resourceClass)), e
);
}
}
}
} return map.get(resourceClass);
}
}

5.5 注册类型是jdk proxy类型的bean

//参数dynamicProxyClass 是 ProviderDynamicProxy
public static boolean registerProvider(BeanDefinitionRegistry registry, Class<?> dynamicProxyClass, Class<?> resourceClass) {
String apiClassInfo = ClassUtils.getQualifiedName(resourceClass);
try {
/**
* 通过代理bean的方式创建创建 服务bean
* @see com.hjzgg.apigateway.dubbo.configure.SelfDubboAnnotationBean#postProcessAfterInitialization(Object, String)
* if (AopUtils.isAopProxy(bean)), 判断bean的类型如果是代理类型,进行dubbo注解解析处理
* */
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(resourceClass);
String dubboVersion = resourceClass.getAnnotation(Service.class).version();
String dubboGroup = resourceClass.getAnnotation(Service.class).group();
ProviderProxyFactoryBean providerProxyFactoryBean = new ProviderProxyFactoryBean(dynamicProxyClass, resourceClass, dubboVersion, dubboGroup);
/**
* providerProxyFactoryBean.getObject() 得到的是通过 Proxy.newInstance方法获取到的代理类
* @see com.hjzgg.apigateway.soa.proxy.DynamicProxyAdapter#createJDKProxy(ProxyFactoryBean, Class)
* 可通过 Proxy.getInvocationHandler方法拿到 InvocationHandler实例
*/
Class<?> targetProxyClass = ProviderProxyFactoryBean.getProxyClass(resourceClass);
builder.addConstructorArgValue(Proxy.getInvocationHandler(providerProxyFactoryBean.getObject()));
AbstractBeanDefinition beanDefinition = builder.getBeanDefinition();
beanDefinition.setBeanClass(targetProxyClass); beanDefinition.setAttribute(Constants.API_CLASS_INFO, resourceClass);
String beanName = beanNameGenerator.generateBeanName(beanDefinition, registry);
if (registry.containsBeanDefinition(beanName)) {
log.debug(beanName + " already exists! Class is " + apiClassInfo + " .");
return false;
}
registry.registerBeanDefinition(beanName, beanDefinition);
return true;
} catch (Exception e) {
log.error("registerProvider proxy bean error! Class is " + apiClassInfo + " .");
return false;
}
}

5.6 附加SelfDubboAnnotationBean

package com.hjzgg.apigateway.dubbo.configure;

import com.alibaba.dubbo.common.Constants;
import com.alibaba.dubbo.common.logger.Logger;
import com.alibaba.dubbo.common.logger.LoggerFactory;
import com.alibaba.dubbo.common.utils.ConcurrentHashSet;
import com.alibaba.dubbo.config.*;
import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.dubbo.config.spring.ReferenceBean;
import com.alibaba.dubbo.config.spring.ServiceBean;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.util.ClassUtils; import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.stream.Collectors;
import java.util.stream.Stream; /**
* @see com.alibaba.dubbo.config.spring.AnnotationBean
*/
public class SelfDubboAnnotationBean extends AbstractConfig implements DisposableBean, BeanPostProcessor, ApplicationContextAware, Serializable { private static final Logger logger = LoggerFactory.getLogger(Logger.class); private String annotationPackage; private String[] annotationPackages; private final Set<ServiceConfig<?>> serviceConfigs = new ConcurrentHashSet<>(); private final ConcurrentMap<String, ReferenceBean<?>> referenceConfigs = new ConcurrentHashMap<>(); public String getPackage() {
return annotationPackage;
} public void setPackage(String annotationPackage) {
this.annotationPackage = annotationPackage;
this.annotationPackages = (annotationPackage == null || annotationPackage.length() == 0) ? null
: Constants.COMMA_SPLIT_PATTERN.split(annotationPackage);
} private ApplicationContext applicationContext; public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
} public void destroy() throws Exception {
for (ServiceConfig<?> serviceConfig : serviceConfigs) {
try {
serviceConfig.unexport();
} catch (Throwable e) {
logger.error(e.getMessage(), e);
}
}
for (ReferenceConfig<?> referenceConfig : referenceConfigs.values()) {
try {
referenceConfig.destroy();
} catch (Throwable e) {
logger.error(e.getMessage(), e);
}
}
} public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
if (! isMatchPackage(bean)) {
return bean;
}
if (AopUtils.isAopProxy(bean)) {
/**
* @see com.hjzgg.apigateway.soa.executor.RegisterBeanUtils#registerProvider
* @see com.hjzgg.apigateway.soa.proxy.provider.ProviderDynamicProxy#invoke
* */
//获取被代理的真实类或者接口类
Class<?> targetClass = AopUtils.getTargetClass(bean);
Service service = targetClass.getAnnotation(Service.class);
if (service != null) {
ServiceBean<Object> serviceConfig = new ServiceBean<Object>(service);
if (void.class.equals(service.interfaceClass())
&& "".equals(service.interfaceName())) {
if (!(targetClass.isInterface() || targetClass.getInterfaces().length > 0)) {
throw new IllegalStateException("Failed to export remote service class " + bean.getClass().getName() + ", cause: The @Service undefined interfaceClass or interfaceName, and the service class unimplemented any interfaces.");
} else {
if (targetClass.isInterface()) {
serviceConfig.setInterface(targetClass);
} if (targetClass.getInterfaces().length > 0) {
serviceConfig.setInterface(targetClass.getInterfaces()[0]);
}
}
}
if (applicationContext != null) {
serviceConfig.setApplicationContext(applicationContext);
if (service.registry() != null && service.registry().length > 0) {
List<RegistryConfig> registryConfigs = new ArrayList<RegistryConfig>();
for (String registryId : service.registry()) {
if (registryId != null && registryId.length() > 0) {
registryConfigs.add(applicationContext.getBean(registryId, RegistryConfig.class));
}
}
serviceConfig.setRegistries(registryConfigs);
}
if (service.provider() != null && service.provider().length() > 0) {
serviceConfig.setProvider(applicationContext.getBean(service.provider(),ProviderConfig.class));
}
if (service.monitor() != null && service.monitor().length() > 0) {
serviceConfig.setMonitor(applicationContext.getBean(service.monitor(), MonitorConfig.class));
}
if (service.application() != null && service.application().length() > 0) {
serviceConfig.setApplication(applicationContext.getBean(service.application(), ApplicationConfig.class));
}
if (service.module() != null && service.module().length() > 0) {
serviceConfig.setModule(applicationContext.getBean(service.module(), ModuleConfig.class));
}
if (service.provider() != null && service.provider().length() > 0) {
serviceConfig.setProvider(applicationContext.getBean(service.provider(), ProviderConfig.class));
}
if (service.protocol() != null && service.protocol().length > 0) {
List<ProtocolConfig> protocolConfigs = new ArrayList<ProtocolConfig>();
for (String protocolId : service.registry()) {
if (protocolId != null && protocolId.length() > 0) {
protocolConfigs.add(applicationContext.getBean(protocolId, ProtocolConfig.class));
}
}
serviceConfig.setProtocols(protocolConfigs);
}
try {
serviceConfig.afterPropertiesSet();
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new IllegalStateException(e.getMessage(), e);
}
}
serviceConfig.setRef(bean);
serviceConfigs.add(serviceConfig);
serviceConfig.export();
}
}
return bean;
} public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { Service service = (AopUtils.isAopProxy(bean) && !Objects.isNull(AopUtils.getTargetClass(bean).getAnnotation(Service.class)))
? AopUtils.getTargetClass(bean).getAnnotation(Service.class)
: bean.getClass().getAnnotation(Service.class);
if (Objects.isNull(service)) {
return bean;
}
try {
InvocationHandler h = Proxy.getInvocationHandler(service); // 获取 AnnotationInvocationHandler 的 memberValues 字段
Field memberValuesField = h.getClass().getDeclaredField("memberValues");
// 因为这个字段事 private final 修饰,所以要打开权限
memberValuesField.setAccessible(true);
// 获取 memberValues
Map memberValues = (Map) memberValuesField.get(h); Service serviceInstance = Stream.of(bean.getClass().getInterfaces())
.filter(iface -> iface.getAnnotation(Service.class) != null)
.collect(Collectors.toList())
.get(0)
.getAnnotation(Service.class); memberValues.put("version", serviceInstance.version());
memberValues.put("group", serviceInstance.group());
} catch (Exception e) {
throw new BeanCreationException(String.format("%s %s %s %s %s"
, "修改"
, ClassUtils.getQualifiedName(bean.getClass())
, "的注解"
, ClassUtils.getQualifiedName(Service.class)
, "的 group值和version值出错")
, e);
}
return bean;
} private boolean isMatchPackage(Object bean) {
if (annotationPackages == null || annotationPackages.length == 0) {
return true;
}
String beanClassName = bean.getClass().getName();
for (String pkg : annotationPackages) {
if (beanClassName.startsWith(pkg)) {
return true;
}
}
return false;
} }

5.7 附加AopUtils相关方法

/**
* Check whether the given object is a JDK dynamic proxy or a CGLIB proxy.
* <p>This method additionally checks if the given object is an instance
* of {@link SpringProxy}.
* @param object the object to check
* @see #isJdkDynamicProxy
* @see #isCglibProxy
*/
public static boolean isAopProxy(Object object) {
return (object instanceof SpringProxy &&
(Proxy.isProxyClass(object.getClass()) || ClassUtils.isCglibProxyClass(object.getClass())));
} /**
* Determine the target class of the given bean instance which might be an AOP proxy.
* <p>Returns the target class for an AOP proxy or the plain class otherwise.
* @param candidate the instance to check (might be an AOP proxy)
* @return the target class (or the plain class of the given object as fallback;
* never {@code null})
* @see org.springframework.aop.TargetClassAware#getTargetClass()
* @see org.springframework.aop.framework.AopProxyUtils#ultimateTargetClass(Object)
*/
public static Class<?> getTargetClass(Object candidate) {
Assert.notNull(candidate, "Candidate object must not be null");
Class<?> result = null;
if (candidate instanceof TargetClassAware) {
result = ((TargetClassAware) candidate).getTargetClass();
}
if (result == null) {
result = (isCglibProxy(candidate) ? candidate.getClass().getSuperclass() : candidate.getClass());
}
return result;
}

spring AbstractBeanDefinition创建bean类型是动态代理类的方式的更多相关文章

  1. Spring学习(四)—— java动态代理(JDK和cglib)

    JAVA的动态代理 代理模式 代理模式是常用的java设计模式,他 的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托 ...

  2. CGLIB 和 JDK生成动态代理类的区别(转)

    文章转自http://luyuanliang.iteye.com/blog/1137292 AOP 使用的设计模式就是代理模式,是对IOC设计的补充.为了扩展性,往往会加上反射,动态生成字节码,生成代 ...

  3. 【转载】Spring AOP详解 、 JDK动态代理、CGLib动态代理

    Spring AOP详解 . JDK动态代理.CGLib动态代理  原文地址:https://www.cnblogs.com/kukudelaomao/p/5897893.html AOP是Aspec ...

  4. 【spring基础】AOP概念与动态代理详解

    一.代理模式 代理模式的英文叫做Proxy或Surrogate,中文都可译为”代理“,所谓代理,就是一个人或者一个机构代表另一个人或者另一个机构采取行动.在一些情况下,一个客户不想或者不能够直接引用一 ...

  5. Spring之IOC,DI,动态代理,反射

    Spring框架是J2EE开发中一个使用广泛的框架,它使得dao和service层的维护更加便利.Spring框架有两个重要的特征,一个是IOC,另一个是AOP.我们在这里主要介绍IOC,以及IOC中 ...

  6. 七 MyBatis整合Spring,DAO开发(传统DAO&动态代理DAO)

    整合思路: 1.SQLSessionFactory对象应该放到Spring中作为单例存在 2.传统dao开发方式中,应该从Spring容器中获得SqlSession对象 3.Mapper代理行驶中,应 ...

  7. 浅析Spring中AOP的实现原理——动态代理

    一.前言   最近在复习Spring的相关内容,刚刚大致研究了一下Spring中,AOP的实现原理.这篇博客就来简单地聊一聊Spring的AOP是如何实现的,并通过一个简单的测试用例来验证一下.废话不 ...

  8. 50、[源码]-Spring容器创建-Bean创建完成

    50.[源码]-Spring容器创建-Bean创建完成 11.finishBeanFactoryInitialization(beanFactory);初始化所有剩下的单实例bean: beanFac ...

  9. spring框架中JDK和CGLIB动态代理区别

    转载:https://blog.csdn.net/yhl_jxy/article/details/80635012 前言JDK动态代理实现原理(jdk8):https://blog.csdn.net/ ...

随机推荐

  1. Mysql 插入中文错误:Incorrect string value: '\xE7\xA8\x8B\xE5\xBA\x8F...' for column 'course' at row 1

    create table my_user (    id tinyint(4) not null auto_increment,    account varchar(255) default nul ...

  2. oracle存储过程,sql语句执行时间

    create or replace procedure sum_info is i integer; temp1 varchar2(50); temp2 varchar2(50); t1 date; ...

  3. Windows和Mac上NodeJS和Express的安装

    一.安装NodeJS,官网上下载,https://nodejs.org/en/ 直接下一步安装就行了. 打开命令行工具,输入 node -v 则会出现node的版本,则成功了. 下面我们介绍如何安装e ...

  4. 【转】PyDev Eclipse使用技巧说明

    PyDev Package Explorer 创建项目 在开展工作之前,需要创建一个新的项目.在 Eclipse 菜单栏中,选择 File > New > Project > Pyd ...

  5. python学习之argparse模块

    python学习之argparse模块 一.简介: argparse是python用于解析命令行参数和选项的标准模块,用于代替已经过时的optparse模块.argparse模块的作用是用于解析命令行 ...

  6. GCC制作动态库导出符号表【转】

    转自:https://blog.csdn.net/whb_fei/article/details/76974543 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.cs ...

  7. mysql binglog server的设置方法【原创】

    MySQL备份数据都是MySQL备份+binlog,这样才能保证数据的完整性.下面就是利用mysqlbinlog搭建mysql binlog server,可以把binlog传到远程存储上. 试验环境 ...

  8. plsql developer导入导出序列方法

    导出: 1.打开PLSQL Developer,工具 2.类型排序,选中所有sequence,指定用户,单个文件,选择导出文件路径,等待执行完毕即可. 导入: 打开导出的文件,复制,在新打开的命令窗口 ...

  9. centos6下通用二进制安装mysql5.5.33

    mysql5.5通用二进制格式安装方法 1.解压到 /usr/local 目录 # tar xf mysql-5.5.33-linux2.6-x86_64.tar.gz -C /usr/local 2 ...

  10. nginx转发

    1.下载nginx:官网(http://nginx.org)右侧下载,进入下载页,选在需要下载的版本 2.将压缩包解压到指定的目录下 (D:\Environments\nginx-1.8.0) 3.启 ...