前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >CGLib浅析

CGLib浅析

作者头像
张小驰出没
发布于 2021-12-06 08:42:57
发布于 2021-12-06 08:42:57
52800
代码可运行
举报
运行总次数:0
代码可运行

CGLib浅析

什么是CGLib

CGLIB实现动态代理,并不要求被代理类必须实现接口,底层采用asm字节码生成框架生成代理类字节码(该代理类继承了被代理类)。

所以被代理类一定不能定义为final class并且对于final 方法不能被代理。

实现需要

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//MethodInterceptor接口的intercept方法
/**
*obj 代理对象
*method 委托类方法,被代理对象的方法字节码对象
*arg 方法参数
*MethodProxy 代理方法MethodProxy对象,每个方法都会对应有这样一个对象 
*/
public Object intercept(Object obj, Method method, Object[] arg, MethodProxy proxy)
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Ehancer enhancer = new Enhancer() //Enhancer为字节码增强器,很方便对类进行扩展
enhancer.setSuperClass(被代理类.class);
enhancer.setCallback(实现MethodInterceptor接口的对象)
enhancer.create()

代码案例

导入依赖

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<dependency>
  <groupId>cglib</groupId>
  <artifactId>cglib</artifactId>
  <version>3.3.0</version>
</dependency>

UserDaoImpl 用户实现类(RealSubject)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class UserDaoImpl {
    public boolean insert(String name) {
        System.out.println("insert name=" + name);
        return true;
    }

    public final boolean insert1(String name) {
        System.out.println("final insert name=" + name);
        return true;
    }
}

CglibProxy CGLIB代理类(Proxy)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class CglibProxy implements MethodInterceptor {
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("----------before----------");
        System.out.println("Proxy=" + o.getClass());
        System.out.println("method=" + method);
        System.out.println("args=" + Arrays.toString(objects));
        System.out.println("methodProxy=" + methodProxy);
        //执行目标方法对象
        Object result = methodProxy.invokeSuper(o, objects);
        System.out.println("----------after----------");
        return result;
    }
}

ProxyFactory 代理工厂

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class ProxyFactory {
    private static Enhancer enhancer = new Enhancer();
    private static CglibProxy cglibProxy = new CglibProxy();
    
    public static Object getProxy(Class cls) {
        enhancer.setSuperclass(cls);
        enhancer.setCallback(cglibProxy);
        return enhancer.create();
    }
    
    public static void main(String[] args) {
        UserDaoImpl userDao = (UserDaoImpl) getProxy(UserDaoImpl.class);
        userDao.insert("zc");
    }
}

CGLib流程

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Ehancer enhancer = new Enhancer() //Enhancer为字节码增强器,很方便对类进行扩展
enhancer.setSuperClass(被代理类.class);    //为生成的类设置父类
enhancer.setCallback(实现MethodInterceptor接口的对象);
enhancer.create();    //创建代理对象

创建代理对象会经过三步:

1.生成代理类的二进制字节码文件。

2.加载二进制字节码文件到JVM,生成class对象。

3.反射获得实例构造方法,创建代理对象。

接下来,看看反编译出现的Java文件

CGLib反编译方法

  • 使用以下语句
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "D:\\xxxx")
  • 使用HSDB进行反编译
  • 使用 arthas 配合 jad进行反编译

具体使用方法可以自行查找

我们以insert() 为入口开始:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
UserDaoImpl userDao = (UserDaoImpl) getProxy(UserDaoImpl.class);  //Ehancer,创建代理对象
userDao.insert("zc");

这时候会进入UserDaoImplUserDaoImpl$$EnhancerByCGLIB$$f32f6ae2中的insert()

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public final boolean insert(String string) {
    MethodInterceptor methodInterceptor = this.CGLIB$CALLBACK_0;
    if (methodInterceptor == null) {
        UserDaoImpl$$EnhancerByCGLIB$$f32f6ae2.CGLIB$BIND_CALLBACKS(this);
        methodInterceptor = this.CGLIB$CALLBACK_0;
    }
    if (methodInterceptor != null) {
        Object object = methodInterceptor.intercept(this, CGLIB$insert$0$Method, new Object[]{string}, CGLIB$insert$0$Proxy);
        return object == null ? false : (Boolean)object;
    }
    return super.insert(string);
}

其实在上述方法中,是因为设置了 enhancer.setCallback(cglibProxy); ,只要不为空,则会执行

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Object object = methodInterceptor.intercept(this, CGLIB$insert$0$Method, new Object[]{string}, CGLIB$insert$0$Proxy);

this : 当前代理对象 CGLIBsay0 CGLIB$emptyArgs : 方法参数,这里为空 CGLIBsay0

这样会去调用 CglibProxy.intercept() 方法

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
 * Object:cglib生成的代理对象
 * Method:被代理对象方法
 * Object[]:方法入参
 * MethodProxy:代理的方法
 */
public class CglibProxy implements MethodInterceptor {
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("----------before----------");
        
        //执行目标方法对象
        Object result = methodProxy.invokeSuper(o, objects);

        System.out.println("----------after----------");
        return result;
    }
}

这时候进入 methodProxy.invokeSuper(o, objects) 方法

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public Object invokeSuper(Object obj, Object[] args) throws Throwable {
    try {
        init();
        FastClassInfo fci = fastClassInfo;
        return fci.f2.invoke(fci.i2, obj, args);
    } catch (InvocationTargetException e) {
        throw e.getTargetException();
    }
}

第一反应,可能不知道是f2i2 都是什么,这里扯一下 init() 方法,其中对于FastClass 类,就是反编译出来的对应类:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
private void init()
{
    if (fastClassInfo == null)
    {
        synchronized (initLock)
        {
            if (fastClassInfo == null)
            {
                CreateInfo ci = createInfo;
                FastClassInfo fci = new FastClassInfo();
                fci.f1 = helper(ci, ci.c1);    // 被代理类FastClass
                fci.f2 = helper(ci, ci.c2);    // 代理类FastClass
                fci.i1 = fci.f1.getIndex(sig1); // 被代理类的方法签名(index)
                fci.i2 = fci.f2.getIndex(sig2); // 代理类的方法签名(index)
                fastClassInfo = fci;
                createInfo = null;
            }
        }
    }
}

private static class FastClassInfo
{
    FastClass f1;  // 被代理类FastClass
    FastClass f2;  // 代理类FastClass
    int i1;  // 被代理类的方法签名(index)
    int i2;  // 代理类的方法签名(index)
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
fci.f2 = helper(ci, ci.c2);    // 代理类FastClass
fci.i2 = fci.f2.getIndex(sig2); // 代理类的方法签名(index)

这时候看到UserDaoImpl$$EnhancerByCGLIB$$f32f6ae2$$FastClassByCGLIB$$9fc87de5

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Override
public int getIndex(Signature signature) {
    String string = ((Object)signature).toString();
    switch (string.hashCode()) {
         //XXXXX 省略
            
        case -747055045: {
            if (!string.equals("CGLIB$insert$0(Ljava/lang/String;)Z")) break;
            return 16;
        }
            
       //XXXXX 省略
    return -1;
}

所以 i2 在其中为 16 , 这时候运行下面方法

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
fci.f2.invoke(fci.i2, obj, args)

即,UserDaoImpl$$EnhancerByCGLIB$$f32f6ae2$$FastClassByCGLIB$$9fc87de5invoke()方法

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Override
public Object invoke(int n, Object object, Object[] objectArray) throws InvocationTargetException {
    UserDaoImpl$$EnhancerByCGLIB$.f32f6ae2 f32f6ae22 = (UserDaoImpl$$EnhancerByCGLIB$.f32f6ae2)object;
    try {
        switch (n) {
             //XXXXX 省略
            case 16: {
                return new Boolean(f32f6ae22.CGLIB$insert$0((String)objectArray[0]));
            }
            //XXXXX 省略
        }
    }
    catch (Throwable throwable) {
        throw new InvocationTargetException(throwable);
    }
    throw new IllegalArgumentException("Cannot find matching method/constructor");
}

可以看到,他进行调用的是 UserDaoImpl$$EnhancerByCGLIB$f32f6ae2中的CGLIB$insert$0()方法

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
final boolean CGLIB$insert$0(String string) {
    return super.insert(string);
}

这里,才是真正调用到了父类(目标类)中对应的方法。至此,整个的调用流程完毕。

流程总结

  1. 首先生成代理对象。创建增强类enhancer,设置代理类的父类,设置回调拦截方法,返回创建的代理对象;
  2. 调用代理类中的方法。这里调用的代理类中的方法实际上是重写的父类的拦截。重写的方法中会去调用intercept方法;
  3. 调用intercept,方法中会对调用代理方法中的invokeSuper方法。而在 invokeSuper 中维护了一个 FastClassInfo类,其包含四个属性字段,分别为FastClass f1(目标类)FastClass f2 (代理类)int i1(目标类要执行方法的下标)int i2(代理类要执行方法的下标); invokeSuper中会调用的为代理类中的对应方法(代理类继承于父类的时候,对于其父类的方法,自己会生成两个方法,一个是重写的方法,一个是代理生成的方法,这里调用的即是代理生成的方法);
  4. 调用代理类中的代理方法。代理方法中通过super.xxxx(string)来实际真正的调用要执行的方法;

思考

JDK动态代理CGLib动态代理 有什么本质区别?

首先我们可以回想一下JDK动态代理CGLib动态代理,两者代理类中的区别:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//CGLib
private static Enhancer enhancer = new Enhancer();
private static CglibProxy cglibProxy = new CglibProxy();

public static Object getProxy(Class cls) {
  enhancer.setSuperclass(cls);
  enhancer.setCallback(cglibProxy);
  return enhancer.create();
}

public static void main(String[] args) throws InterruptedException {
  UserDaoImpl userDao = (UserDaoImpl) getProxy(UserDaoImpl.class);
  userDao.insert("zc");
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//JDK
public static Object getProxy(Object proxyObj) {
  return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
                                proxyObj.getClass().getInterfaces(), new MyInvocationHandler(proxyObj));
}

public static void main(String[] args) {
  AgeDao ageDao = (AgeDao) getProxy(new NameAndAgeDaoImpl());
  ageDao.addAge(20);
}

我理解,这2种动态代理,最本质的区别就是:JDK动态代理是基于委托思想,而CGLib动态代理是基于继承的思想。

基于委托思想,JDK生成动态代理类的时候,需要传入被代理类(被委托类)的对象,可以看作是对象级别的重用机制

基于继承思想,动态代理类继承了被代理类,理论上父类的所有开放方法对于子类都是可见的,可以看作是级别的重用机制;

而怎么理解上面的话呢,这就要回归到动态代理的本质:

动态代理 = 拦截器机制 + 回溯到被代理类的能力

  • 对于JDK动态代理:

JDK动态代理 = 拦截器机制(InvocationHandler) + 回溯到被代理类的能力(反射调用被代理类对象相关方法)

在JDK动态代理中,生成的代理类的全限定类名是com.sun.proxy.ProxyN(N是正整数,比如Proxy0),它继承了com.sun.proxy类,该类中存在一个InvocationHandler类型的h成员变量,它就是拦截器。但这里会存在一个问题,由于我们希望代理类和被代理类在行为上是一致的(具有相同的类型),所以JDK动态代理需要引入接口的概念,代理对象和被代理对象需要具有相同的接口定义。

所以,在我们使用JDK动态代理的过程中,我们需要自定义拦截器,实现InvocationHandler 接口,然后将被代理对象(被委托对象)注入到拦截器中。当调用接口方法时,会首先调用拦截器的invoke方法,拦截器invoke方法内部,会经过反射去调用被代理对象的相应方法。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class MyInvocationHandler implements InvocationHandler {
    private Object target;
    public MyInvocationHandler(Object target) {
        this.target = target;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //执行目标方法对象
        Object result = method.invoke(target, args);
        return result;
    }
}
  • 对于CGLIB动态代理:

CGLIB动态代理 = 拦截器机制(MethodInterceptor) + 回溯到被代理类的能力 (FastClass辅助类、MethodProxy类)

CGLIB动态代理中,生成的代理类的全限定类名是很自由的。因为它是基于继承机制,代理类继承了被代理类。 在生成的代理类中,会存在一个MethodInterceptor类型的CGLIB$CALLBACK_0成员变量,它就是拦截器。**由于是继承,代理类天然就可以调用到父类(被代理类)的方法,因此这里不再需要注入被代理类的对象实例了。**但这里仍然存在一个很核心的问题:代理类看起来,既要能够调用到拦截器,又要可以回溯到父类(被代理类)的原始方法,这看起来很矛盾。怎么解决呢?

其实很简单,CGLIB生成的代理,对于被代理类的原有方法(比如上面的insert方法),会调用到拦截器。而与此同时,CGLIB还增加了隐藏的能够回溯到原始方法的传送门方法(比如CGLIBinsert0),这样就可以两全其美了。

可是问题又来了,拦截器是我们自己来实现并添加业务自定义逻辑的,当我们想要在拦截器里调用到原始的被代理对象的insert方法,该如何去实现呢?

一种可行的方式是使用反射,调用代理对象的隐藏传送门CGLIBinsert0方法。不得不说,这的确是可行的,但成本也非常大,你需要提前反编译动态代理的源码,找到对应的方法名。而动态代理之所以被称为动态代理,核心在于它是在jvm运行期动态生成的,所以这并不符合我们的初衷。而且要让拦截器对所有的方法进行适配,这显然也不现实。

我们说,没有什么问题不能通过加一层解决,CGLIB又一次证明了它的正确性。为了解决这个问题,CGLIB框架引入了MethodProxy的概念。针对每一个被代理对象的方法(比如insert),都有一个MethodProxy,它对外提供了invokeSuper和invoke方法,分别可以路由到CGLIBinsert0和insert方法。

所以,我们在拦截器做拦截操作时,直接调用对应MethodProxyinvokeSuper就可以路由到代理对象的隐藏传送门方法啦。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class CglibProxy implements MethodInterceptor {   
    @Override   
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {    
        //执行目标方法对象       
        Object result = methodProxy.invokeSuper(o, objects);      
        return result;   
    }
}
  • 两者区别
  1. JDK动态代理基于接口实现,必须先定义接口CGLib动态代理基于被代理类实现,可以直接定义或者实现接口的类
  2. JDK动态代理需要实现InvocationHanlder接口,加上反射机制实现代理类 CGLib动态代理需要实现MethodInterceptor接口,对于代理类不可使用final修饰
  3. JDK动态代理是委托机制,委托hanlder,生成新的委托类,调用实现类方法; CGLib动态代理则使用继承机制,被代理类和代理类是继承关系,直接调用其中方法;

在其中FastClass类发挥了什么作用呢?为什么要有FastClass类

我在上面称FastClass类为辅助类:

  • 首先在invoke()invokeSuper()中都存在FastClass
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public Object invoke(Object obj, Object[] args) throws Throwable {	
    //初始化 
    return fci.f1.invoke(fci.i1, obj, args);	
    //XXXXX 省略
}

public Object invokeSuper(Object obj, Object[] args) throws Throwable { 
    //初始化  
    return fci.f2.invoke(fci.i2, obj, args);	
    //XXXXX 省略
}

private static class FastClassInfo{  
    FastClass f1; // UserDaoImpl$$FastClassByCGLIB$$481edb7a  
    FastClass f2; // UserDaoImpl$$EnhancerByCGLIB$$f32f6ae2$$FastClassByCGLIB$$9fc87de5  
    int i1;  
    int i2;
}

在上面的举例中可以看到,在生成的代理类、被代理类的FastClass类中,有 getindex()、invoke()等,获取索引,通过索引调用方法等。所以我称为 FastClass辅助类

在JDK动态代理中,调用目标对象的方法使用的是反射,而在CGLIB动态代理中使用的是FastClass机制

  1. FastClass使用:动态生成一个继承FastClass的类,并向类中写入委托对象,直接调用委托对象的方法。
  2. FastClass逻辑:在继承FastClass的动态类中,根据方法签名(方法名字+方法参数)得到方法索引,根据方法索引调用目标对象方法。
  3. FastClass优点:FastClass用于代替Java反射,避免了反射造成调用慢的问题。

明明下面两个方法中都有 super.xxxx(string) , 但是使用的是 invokeSuper() ,而不是 invoke()

看下这两个方法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
final boolean CGLIB$insert$0(String string) {   
    return super.insert(string);
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public final boolean insert(String string) {   
    MethodInterceptor methodInterceptor = this.CGLIB$CALLBACK_0;   
    if (methodInterceptor == null) {       
        UserDaoImpl$$EnhancerByCGLIB$$f32f6ae2.CGLIB$BIND_CALLBACKS(this);      
        methodInterceptor = this.CGLIB$CALLBACK_0;   
    }   
    if (methodInterceptor != null) {       
        Object object = methodInterceptor.intercept(this, CGLIB$insert$0$Method, new Object[]{string}, CGLIB$insert$0$Proxy);   
        return object == null ? false : (Boolean)object;   
    }    
    return super.insert(string);
}
  • 如果使用invokeSuper()
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public Object invokeSuper(Object obj, Object[] args) throws Throwable {        
    try {           
        init();           
        FastClassInfo fci = fastClassInfo;            
        //执行被代理类FastClass 的对应 i2 索引的方法            
        return fci.f2.invoke(fci.i2, obj, args);        
    } catch (InvocationTargetException e) {           
        throw e.getTargetException();       
    }    
}

就是按照上面讲的步骤,先进行 insert() 方法,经过intercept,最终可以运行到 CGLIBinsert0() ,调用到了父类(目标类)中对应的方法。

  • 如果使用invoke()
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public Object invoke(Object obj, Object[] args) throws Throwable {    
    try {       
        init();      
        FastClassInfo fci = fastClassInfo;       
        //执行代理类FastClass 的对应 i1 索引的方法       
        return fci.f1.invoke(fci.i1, obj, args);    
    } catch (InvocationTargetException e) {       
        throw e.getTargetException();   
    } catch (IllegalArgumentException e) {        
        if (fastClassInfo.i1 < 0)           
            throw new IllegalArgumentException("Protected method: " + sig1);       
        throw e;   
    }
}

i1 的值通过下面方法获取为 1

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Overridepublic int getIndex(Signature signature) {   
    String string = ((Object)signature).toString();    
    switch (string.hashCode()) {         
            //XXXXX 省略       
        case -982250262: {           
            if (!string.equals("insert(Ljava/lang/String;)Z"))
                break;           
            return 1;       
        }            
            //XXXXX 省略   
    }    
    return -1;
}

接着,执行对应方法

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Overridepublic Object invoke(int n, Object object, Object[] objectArray) throws InvocationTargetException {   
    UserDaoImpl userDaoImpl = (UserDaoImpl)object;   
    try {       
        switch (n) {         
                //XXXXX 省略         
            case 1: {             
                return new Boolean(userDaoImpl.insert((String)objectArray[0]));         
            }         
                //XXXXX 省略       
        }    
    }    
    catch (Throwable throwable) {        
        throw new InvocationTargetException(throwable);    
    }   
    throw new IllegalArgumentException("Cannot find matching method/constructor");
}

先进行 insert() 方法,经过intercept,通过 invoke() 方法,再次进入insert()方法,继而是一直死循环。

个人博客为: MoYu’s HomePage

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021/09/11 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
可穿戴无人机要取代智能手机?
---- 美国知名设计公司Frog计划与其他公司合作,使其可穿戴无人机原型产品成为现实。Frog的设计曾被用于索尼Walkman和苹果IIc计算机。根据Frog的设想,无人机可以佩戴在脖子上或手腕上,
机器人网
2018/04/19
4430
可穿戴无人机要取代智能手机?
可穿戴式物联网可以做什么
可穿戴技术并非完全是新技术。最早的可穿戴技术是1286年发明的,当时眼镜首次使近视者能够清楚地看到远距离。在整个20世纪,小工具制造商都喜欢将新技术应用于头带,手表和鞋子,即使它降低了功能性。
用户4122690
2020/04/03
9520
可穿戴式物联网可以做什么
2016年值得关注的13项穿戴式技术发展趋势
Apple Watch与Huawei Watch 51CTO授权转载 作者:核子可乐 网站:http://mobile.51cto.com 摘要:Fitbit能否在2016年继续笑傲运动追踪设备市场?消费者是否愿意为根据运动追踪设备收集并整理出的分析结论买单?这类信息的安全性又是否值得信赖?可穿戴技术专家们将尝试回答这些问题,并分享新一年中与之相关的预测观点。 Apple Watch在2015年当中一直成为可穿戴式设备领域的关注重点,而且这一趋势很可能在2016年当中继续延续。Fitbit也可能在新的一
大数据文摘
2018/05/23
3590
可穿戴设备:苹果“吃老底”、华为“忙复苏”、小米“再扩容”
随着产品功能的创新,可穿戴设备不再被简单地视为手机的延伸,而是被当成一种独立的、具有独特功能和优势的产品,受到了越来越多人的青睐。
刘旷
2024/06/17
1060
可穿戴设备:来看看水面之下的冰山
兼具“可穿戴设备之父”和“全球七大大数据专家之一”名号的阿莱克斯•彭特兰在一个下午的THE BIG TALK给中国媒体带来一场科技的思想盛宴。尽管彭兰特所提到的大数据和社交网络也是我感兴趣的领域,但因其“可穿戴设备”之父的身份,我想先更多聚焦到其关于可穿戴的观点。听完彭兰特的演讲之后,我认为国内对可穿戴设备的理解还有些肤浅,手环、手表、眼镜,或者直接将其等同于个人健康设备,均是盲人摸象。 一、手环和手表,只是可穿戴设备的冰山一角 Google Glass将可穿戴设备带入大众视野,这款革命性的产品的操盘手正
罗超频道
2018/04/25
6000
「深度」智能可穿戴设备将走向轻奢化?
目前,可穿戴设备面临着这样的尴尬:作为采集数据的入口却还不能提供紧密的专业服务。不过,从徒有概念走向技术成熟,这也是每个领域处于“婴儿期“必然要面对的过程。既然在当下的智能可穿戴设备难以在短期内寻求技
镁客网
2018/05/25
4830
可穿戴设备:想止住颓势,首先需要理清产品属性
去年,CES展会特地为可穿戴设备开辟了一块独立的展馆,到了今年,这项“特权”被取消了,原因嘛,相信大家心里是门儿清。 据IDC发布的报告显示,在2016年第三季度,全球可穿戴市场依旧疲软,整体销量为2
镁客网
2018/05/29
3880
2015年可穿戴设备进入井喷发展期
可穿戴式设备市场如移动追踪器、通知装置、智能手表及头戴式显示器等,在2013年开始起飞。市场成长动能可望拉升今年出货量达4千8百万台,根据NPDDisplaySearch可穿戴式设备市场及预测报告显示,随着各厂商陆续推出以及消费者的采用知觉提高,预计于2015年可穿戴式设备市场将达到全球9千2百万台。且同时有别于2013年为止的市场成长动能,2014年起中国大陆将因为消费者对于可穿戴式设备的应用热潮,以及厂商不断提升功能并降低售价的推动下成为全球最大的市场。 可穿戴式设备种类繁多,NPDDisplayS
大数据文摘
2018/05/21
5050
让可穿戴设备更“贴心”:用户体验设计的奥秘
在智能手表、智能眼镜、智能戒指等可穿戴设备已经成为日常标配的今天,用户体验(UX,User Experience)设计的重要性不言而喻。一款可穿戴设备如果仅仅是“炫酷的硬件+强大的算法”组合,而忽略了用户体验,那就像一台配置炸裂但操作系统卡顿的电脑——体验感极差,用户很可能用几天就束之高阁。
Echo_Wish
2025/03/30
1340
让可穿戴设备更“贴心”:用户体验设计的奥秘
重新定义未来:可穿戴设备的创新设计与制造
可穿戴设备从最初的计步器到如今的智能手表、智能眼镜等,已经成为现代生活中的重要组成部分。它不仅提供便捷的健康监测,还促进了人与技术的深度融合。可穿戴设备的设计与制造过程,需要结合科技、人体工程学以及美学,既要满足用户的功能需求,又要兼顾佩戴的舒适性和长时间使用的耐久性。本篇文章将深入探讨可穿戴设备的设计与制造过程中的创新点,并通过代码展示设备数据处理的实际应用。
Echo_Wish
2025/04/09
1620
重新定义未来:可穿戴设备的创新设计与制造
贴身守护还是隐私威胁?可穿戴设备的安全隐忧
在智能科技的推动下,手环、智能手表、健康追踪器等可穿戴设备逐渐成为现代人生活中的标配。从监控心率到记录步数,这些设备无缝融入我们的日常生活,为健康管理和便利性带来了革命性的提升。然而,当我们享受着这些“智能助手”带来的便利时,是否意识到它们也可能成为隐私泄露和安全问题的潜在威胁?今天,我们将深入剖析可穿戴设备的安全性问题,并提供防护思路。
Echo_Wish
2025/04/03
1470
贴身守护还是隐私威胁?可穿戴设备的安全隐忧
可穿戴智能服装可能是你未来穿衣风格的风向标
在智能硬件遍地开花的今天,手表、鞋子、眼镜、头盔都可以随时随地为你提供意想不到的服务,诸如一抬手就可以浏览邮件,不用再掏手机。行业人士称此为“可穿戴设备”。 可穿戴设备和服饰到底会撞出怎样的火花?也许不久的将来你就可以想象如下情景:在你发光的小礼服上发推文,太阳镜丢了马上就能收到通知,或者让你手上的宝石戒指成为信息提示器。 你是否愿意穿上如此富有未来主义的行头?这也许是个未知数,据研究表明,具有设计性的智能硬件也许是你未来穿衣风格的重要风向标。Gartner公司的数据表明,明年智能服装预计将会超过现下火爆
镁客网
2018/05/25
9210
资本不看好、用户狂吐槽,智能可穿戴设备需要一颗“九转大还丹”
虽然整体市场还在不断增加,但其中的“水分”却令人无法直视。 日前,苹果发布了2017年第二季度的财报,虽然依旧没公布具体的销售数量,但据库克表示,智能手表Apple Watch的销售额比之第一季出现上涨。不过,在销售额上涨的同时,我们也看见了另一则消息,据外媒报道,包括亚马逊、eBay、谷歌地图和Target等多个大牌应用在内,将不再提供Apple Watch应用。其中,谷歌地图的Apple Watch版本已于数周前从软件商店下架。 事实上,此次应用下架事件并没有引起大范围的关注,一方面说明,这些应用在Ap
镁客网
2018/05/28
4570
可穿戴物联网设备能够在恶劣的环境中保护人身安全
原文地址:https://internetofthingsagenda.techtarget.com/blog/IoT-Agenda/Wearable-IoT-devices-guard-personal-safety-in-rugged-environments
Steve Wang
2018/04/26
7900
可穿戴物联网设备能够在恶劣的环境中保护人身安全
谷歌详解Android Wear:大大简化可穿戴产品交互
据国外媒体报道,在I/O开发者大会即将开幕之际,谷歌披露了更多有关Android Wear可穿戴产品界面如何运作的细节信息。 谷歌近日发布的一个YouTube视频对Android Wear软件开发工
大数据文摘
2018/05/21
8240
告别可穿戴 盘点九款可植入体内科技产品
点击标题下「大数据文摘」可快捷关注 摘自:PConline 当我们还在谈论可穿戴智能设备如何引领科技潮流时,智能纹身、医疗芯片等人体可植入设备已悄然来袭,逐渐成为科技弄潮儿们的新宠。人体植入智能产品,这无疑是一个既大胆又新鲜的科技创举。 现阶段,可穿戴设备的确赤手可热,但实际上它们仍然只能算是一种过渡技术,科技的下一个前沿产物或将从我们的体外转移至人体内部。当然,人们仍需一段较长的过程去认知和接受。 1.可遥控的植入式避孕设备 困扰人类数千年的问题,终于有望解决了。实际上,最初提出此想法的正是微软创始
大数据文摘
2018/05/22
7710
可穿戴设备在运动领域的应用:科技让运动更智能
在智能硬件日新月异的今天,可穿戴设备作为其中的佼佼者,正在悄然改变着我们的生活方式,尤其是在运动健康领域。从智能手表到运动手环,越来越多的可穿戴设备将高科技与运动结合,使我们能够更加科学、精准地监测和改善自己的运动表现。在这篇文章中,我们将详细探讨可穿戴设备在运动领域的应用,以及如何通过代码分析运动数据,为我们的健康管理提供更多支持。
Echo_Wish
2025/03/22
1540
可穿戴设备在运动领域的应用:科技让运动更智能
可穿戴技术攻坚战:将心跳变成现金
等到苹果明年春季发布Apple Watch之时,全球将无人不想知道这款让众人期待已久的可穿戴设备到底具备何种功能,佩戴的感觉如何,以及其所代表的含义。不过,关于Apple Watch等可穿戴设备,有一个很重要的问题一直被忽视,即,Apple Watch及其竞争产品所生产出数据的价值。 科技产品现在正在用新方式来测量我们的生活,同样的传感器被赋予了新的使命,被用来测量用户体温、心跳及呼吸速率等,而智能可穿戴设备的生产商则开始思考,如何能够将这些生物特征信息变为可以盈利的服务。 但问题是,据普华永
腾讯研究院
2018/03/13
1.1K0
可穿戴技术攻坚战:将心跳变成现金
人工智能下的可穿戴设备:如何争夺物联网的入口
作者介绍:杨剑勇 传感物联网创建人、物联网资深人士、百强科技名人,著有多篇文章被上千媒体转载,著有《物联网为何萎靡不振:不接地气》、《可穿戴设备出路:设计与科技如何完美融合》,长期关注物联网、人工智能
新智元
2018/03/13
1.8K0
人工智能下的可穿戴设备:如何争夺物联网的入口
可穿戴技术的前景与隐忧
可穿戴设备已经迅速地由幻想变成了极客们的流行风尚,而且正在演变成为继平板电脑之后的下一波大潮。尽管很多人还在嘲笑谷歌眼镜,但是从今年消费电子展(CES)的情况来看,可穿戴技术正被定位为消费电子领域的下一个重大潮流。 尽管媒体上对谷歌眼镜的批评在持续升温,“智能眼镜”的想法却正在很多不同的专业和临床医疗领域中赢得人气。 加利福尼亚大学欧文分校每一名新入学的医科生都会收到用作信息辅助回忆设备的谷歌眼镜。纽约市的一家创业公司已经开发出面向工业应用的智能眼镜,表明这些新技术非常适合多种工业、医疗、零售和产销者应用。
机器人网
2018/04/19
5500
推荐阅读
相关推荐
可穿戴无人机要取代智能手机?
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档