day07-Spring管理Bean-IOC-05

Spring管理Bean-IOC-05

3.基于注解配置bean

3.3自动装配

基本说明:

  1. 基于注解配置bean,也可以实现自动装配,使用的注解是:@AutoWired或者@Resource

  2. @AutoWired 的规则说明

    (1)在IOC容器中查找待装配的组件的类型,如果有唯一的bean装配(按类型),则使用该bean装配

    (2)如果待装配的类型对应的bean在IOC容器中有多个,则使用待装配的属性的属性名作为id值进行查找,找到就装配,找不到就抛异常

  3. @Resource 的规则说明

    (1)@Resource 有两个属性比较重要,分别是name和type

    Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。所以如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType的自动注入策略

    (2)如果@Resource没有指定name或者type,则先使用ByName注入策略,如果匹配不上,再使用byType策略,如果都不成功就会报错

  4. 不管是@AutoWired 还是 @Resource,都保证属性名是规范的写法就可以注入。

  5. 除了有特殊要求,一般推荐使用@Resource

3.3.1应用实例1-@AutoWired

应用实例需求:

  1. 以Action、Service、Dao几个组件来进行演示
  2. 这里演示UserAction和UserService的两级自动组装

UserService:

package com.li.component;

import org.springframework.stereotype.Service;

/**
 * @author 李
 * @version 1.0
 * @Service 标识该类是一个Service类/对象
 */
@Service
public class UserService {
    public void hi(){
        System.out.println("UserService hi()...");
    }
}

UserAction:

package com.li.component;

import org.springframework.stereotype.Controller;

/**
 * @author 李
 * @version 1.0
 * @Controller 标识该类是一个控制器Controller,通常该类是一个Servlet
 */
@Controller
public class UserAction {
    private UserService userService;

    public void sayOk() {
        System.out.println("UserAction 的 sayOk()");
        userService.hi();
    }
}

beans05.xml指定要扫描的包:

<context:component-scan base-package="com.li.component"/>

测试类:

//通过注解来配置Bean
@Test
public void setProByAutowired() {
    ApplicationContext ioc = new ClassPathXmlApplicationContext("beans05.xml");
    UserAction userAction = ioc.getBean("userAction", UserAction.class);
    System.out.println("userAction=" + userAction);
    userAction.sayOk();
}

如下,当运行到userAction.sayOk();时抛出空指针异常:

image-20230120210451954

这是因为userAction中的属性userService指向null,即没有正确的装配UserService对象。

添加@Autowired注解:

在IOC容器中查找待装配的组件的类型,如果有唯一的bean装配(按照类型组装),则使用该bean装配

@Controller
public class UserAction {
    //在IOC容器中查找待装配的组件的类型,如果有唯一的bean装配(按类型),则使用该bean装配
    @Autowired
    private UserService userService;

    public void sayOk() {
        System.out.println("UserAction 的 sayOk()");
        userService.hi();
    }
}

运行结果如下,成功调用了userService.hi()方法,说明userService对象已经成功装配:

image-20230120214336230

现在我们在beans05.xml容器中再配置两个UserService对象

spring允许同时使用xml配置文件和注解的方式配置bean

<context:component-scan base-package="com.li.component"/>

<!--配置两个UserService对象-->
<bean class="com.li.component.UserService" id="userService200"/>
<bean class="com.li.component.UserService" id="userService300"/>

此时在ioc容器中就有三个UserService对象:

(1)对于自动扫描进去的UserService对象,它的id为它的类名(首字母小写)。

(2)在xml文件中配置的两个UserService对象,它们的id为上面设置的id(userService200、userService300)

现在我们重新运行测试方法:

//通过注解来配置Bean
@Test
public void setProByAutowired() {
    ApplicationContext ioc = new ClassPathXmlApplicationContext("beans05.xml");
    UserAction userAction = ioc.getBean("userAction", UserAction.class);
    System.out.println("userAction=" + userAction);
    userAction.sayOk();
}

问题一:运行会不会报错?

问题二:@AutoWired注解的属性进行自动装配的时候,装配的是哪一个UserService对象?

@Autowired
private UserService userService;

答案一:没有报错

image-20230120220340291

答案二: 在@AutoWired注解中,如果待装配的类型对应的bean在IOC容器中有多个,则使用待装配属性的名称作为id值进行查找,找到就装配,找不到就抛异常。因此装配的是ioc容器中id与待装配属性的属性名一致的对象。

3.3.2应用实例2-@Resource

使用UserAction和UserService说明,我们在UserAction类的属性userService400添加@Resource注解,并给@Resource注解添加name属性值=“userService”

package com.li.component;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

import javax.annotation.Resource;

/**
 * @author 李
 * @version 1.0
 * @Controller 标识该类是一个控制器Controller,通常该类是一个Servlet
 */
@Controller
public class UserAction {

    @Resource(name = "userService")
    private UserService userService400;

    public void sayOk() {
        System.out.println("UserAction 的 sayOk()");
        userService400.hi();
    }
}

同时,我们在配置文件beans05.xml文件中又配置了两个UserService对象:

<context:component-scan base-package="com.li.component"/>

<!--配置两个UserService对象-->
<bean class="com.li.component.UserService" id="userService200"/>
<bean class="com.li.component.UserService" id="userService300"/>

也就是说,在beans05.xml文件对应的ioc容器中,此时一共有三个UserService对象:

(1)@Resource注解中配置的名为userService的对象

(2)在xml文件中配置的两个UserService对象,它们的id为上面设置的id(userService200、userService300)

那么在UserAction类的userService400属性中,spring给此属性自动装配的是三个中的哪一个对象呢?

答:id名为“userService”的对象。因为Spring将@Resource注解的name属性解析为bean的名字。 至于UserAction类的属性是什么名字无所谓。


Spring将@Resource注解的type属性则解析为bean的类型。

现在我们将UserAction类中的注解改为type=UserService.class,表示按照UserService.class的类型来进行装配

@Resource(type = UserService.class)
private UserService userService400;

这意味着在ioc容器中,只能有一个UserService类型的对象。如果配置了多个,就会报错:

image-20230121195810659


问题:如果我们在@Resource注解的属性下什么都不写,会如何装配对象?

@Resource
private UserService userService400;

分析如下:现在ioc容器中,还是有三个UserService对象:

(1)@Resource注解中配置的对象(当没有指定name时,该对象对应的id就是“userService”)

(2)xml文件中配置的两个UserService对象,它们的id为上面设置的id(userService200、userService300)

如果@Resource没有指定name或者type,则先使用ByName注入策略,如果匹配不上,再使用byType策略,如果都不成功就会报错。

这里首先使用ByName策略,即匹配userService400,匹配不上后又使用byType策略,显然这里有三个对象,不符合类型匹配。也就是说两种策略都匹配失败,因此结果是:运行出错。

image-20230121202145059

3.3.3注意事项和细节

  1. 如待装配的类型对应的bean在IOC容器中有多个,则使用待装配的属性的属性名作为id值再进行查找,找到就装配,找不到就抛异常 [ByName策略]

  2. 可以使用@Autowired和@Qualifier两个注解配合,可以指定装配对象的id值(注意这个id的对象要在ioc容器中存在)

    @Autowired
    @Qualifier(value = "userService200")
    private UserService userService;
    

3.4泛型依赖注入

基本说明:

  1. 为了更好地管理有继承和相互依赖关系的bean的自动装配,spring还提供基于泛型依赖的注入机制
  2. 泛型依赖注入:子类之间的依赖关系由其父类泛型以及父类之间的依赖关系来确定,父类的泛型必须为同一类型。通俗一点来说:两个子类之间的依赖关系不需要在子类中去声明,而是在父类中进行了声明,而依赖的纽带就是 泛型类型,必须是相同的父类泛型类型才具有依赖关系。
  3. 在继承关系复杂的情况下,泛型依赖注入就会有很大的优越性

应用实例

现有多个类,关系如下:

image-20230121205403499

如上图,如果我们想要在BookService类中使用BookDao属性对象,或者要在PhoneService类中使用PhoneDao对象,传统方法是将 PhoneDao /BookDao自动装配到 BookService/PhoneSerive 中。

但是,当这种继承关系多起来时,即要自动装配的属性多起来时,这种配置方式就显得比较麻烦。因此我们可以使用 spring 提供的泛型依赖注入。

下面模拟图中的类:

Javabean-Phone:

package com.li.depeinjection;

/**
 * @author 李
 * @version 1.0
 */
public class Phone {
}

Javabean-Book:

package com.li.depeinjection;

/**
 * @author 李
 * @version 1.0
 */
public class Book {
}

自定义泛型类BaseDao:

package com.li.depeinjection;

/**
 * @author 李
 * @version 1.0
 * 自定义泛型类
 */
public abstract class BaseDao<T> {
    public abstract void save();
}

BookDao继承BaseDao,指定泛型Book,并添加@Repository注解

package com.li.depeinjection;

import org.springframework.stereotype.Repository;

/**
 * @author 李
 * @version 1.0
 */
@Repository
public class BookDao extends BaseDao<Book> {
    @Override
    public void save() {
        System.out.println("BookDao save()");
    }
}

PhoneDao同样继承BaseDao,指定泛型Phone,并添加@Repository注解

package com.li.depeinjection;

import org.springframework.stereotype.Repository;

/**
 * @author 李
 * @version 1.0
 */
@Repository
public class PhoneDao extends BaseDao<Phone>{
    @Override
    public void save() {
        System.out.println("PhoneDao save()");
    }
}

自定义泛型类BaseService:

package com.li.depeinjection;

import org.springframework.beans.factory.annotation.Autowired;

/**
 * @author 李
 * @version 1.0
 * 自定义泛型类
 */
public class BaseService<T> {
    @Autowired
    private BaseDao<T> baseDao;

    public void save() {
        baseDao.save();
    }
}

BookService继承BaseService,指定泛型Book,并添加@Service注解

package com.li.depeinjection;

import org.springframework.stereotype.Service;

/**
 * @author 李
 * @version 1.0
 */
@Service
public class BookService extends BaseService<Book> {
    //并没有写属性
}

PhoneService也继承BaseService,指定泛型Phone,并添加注解@Service

package com.li.depeinjection;

import org.springframework.stereotype.Service;

/**
 * @author 李
 * @version 1.0
 */
@Service
public class PhoneService extends BaseService<Phone>{
    //并没有写属性
}

在配置文件beans06.xml中配置要扫描的包:

<context:component-scan base-package="com.li.depeinjection"/>

这意味着在com.li.depeinjection包下,添加了四种注解的类将会被进行扫描,在这里就是PhoneService类、BookService类、PhoneDao类、BookDao类

@Controller /@Service/ @Repository/ @Component

现在我们来进行测试:

//通过泛型依赖来配置Bean
@Test
public void setProByDependencyInjection() {
    ApplicationContext ioc = new ClassPathXmlApplicationContext("beans06.xml");
    System.out.println("ok");
}

在语句System.out.println("ok");旁打上断点,点击debug,可以看到在ioc容器中已经有四个对象:

image-20230121214024027

打开ioc-->beanFactory-->singletonObjects-->table属性,展开phoneService对象,可以看到该对象已经自动装载了PhoneDao类型的对象!!

这意味着我们通过泛型依赖注入,可以自动装配需要的对象,不必像之前一样一个个地为属性添加注解。

image-20230121214240496

现在我们获取phoneService对象,调用该对象的save()方法:

//通过泛型依赖来配置Bean
@Test
public void setProByDependencyInjection() {
    ApplicationContext ioc = new ClassPathXmlApplicationContext("beans06.xml");
    PhoneService phoneService = ioc.getBean("phoneService", PhoneService.class);
    phoneService.save();
    System.out.println("ok");
}

因为PhoneService类中没有实现save方法,因此在运行的时候会调用父类BaseService的save()方法,而BaseService的save()方法中又调用了baseDao属性的save()方法.

我们在上图可以知道baseDao的实际对象是PhoneDao类型,根据动态绑定,最终调用了PhoneDao类中的save()方法:

image-20230121215308331
本文转载于网络 如有侵权请联系删除

相关文章

  • 睡前故事|用Bitmap与AST做一个配置化时长系统

    “本文通过编故事的方式讲解bitmap&AST的一个应用场景。这个故事发生在一个网络游戏公司里面,主要登场人物 左边:导师,名字不重要 右边:实习生,三多三多在一家游戏公司做实习生,一天下午他正在划水,被导师叫了过去:三多心里骂娘,但是一想到自己下个月又得交房租了,还是满含泪水打开了需求文档,需求文档大概的意思如下:三多开始一边薅头发,一边设计系统,干到晚上12点,搞出了第一版系统架构图:其中DB表的schema为:字段名类型含义idbigint自增主键user_idbigint用户idstat_datedate统计日期online_durationint用户在线时长总计fight_durationint用户打怪时长总计pet_durationint携带宠物时长总计deal_durationint交易时长总计mining_durationint挖矿时长总计fight_hour_0int0-1点打怪时长总计fight_hour_1int1-2点打怪时长总计...fight_hour_23int23-24点打怪时长总计pet_hour_0int0-1点养宠物时长总计pet_hour

  • 如何开启Nginx缓存

    众所周知,Nginx是一个高性能的web服务器,尤其在高并发和处理静态页面的时候有先天的优势;很大一部分得益于缓存的开启,那么如何开启nginx的缓存呢。简单来说可以分两步: 1.定义缓存存储目录并指定共享内存空间 2.在location里指定共享内存空间具体实现如下:userwww; worker_processesauto; events{ worker_connections4096; } http{ includemime.types; default_typeapplication/octet-stream; sendfileon; gzipon; keepalive_timeout65; #以下是缓存相关配置 proxy_cache_path/data/nginx/cache2levels=1:2keys_zone=mycache:1024mmax_size=2048minactive=1d; server{ listen80; server_namelocalhost; #charsetkoi8-r; #access_loglogs/host.access.logmain

  • c++标准头文件的结构

    参考链接:C++结构标准头文件中一些通用结构的理解 #ifndef_CBPLAYCONTROLWRAPPER#define_CBPLAYCONTROLWRAPPER#ifdef__cplusplusextern"C"{  #endif  /*...*/  #ifdef__cplusplus}#endif#endif/*_CBPLAYCONTROLWRAPPER*/  显而易见,代码第1、2、10行的作用是防止该头文件被重复引用。代码第3行的作用是表示当前使用的是C++编译器。如果要表示当前使用的是C编译器,可以这样指定: #ifdef__STDC__   那么代码第4~8行中的extern“C”有什么作用呢?   extern“C”包含双重含义:   首先,被它修饰的目标是“extern”的。也就是告诉编译器,其声明的函数和变量可以在本模块或其他模块中使用。通常,在模块的头文件中对本模块提供给其他模块引用的函数和全局变量以关键字extern声明。例如,当模块B欲引用该模块A中定义的全局变量和函数时,只需包含模块A的头文件即可。这样,模块B中调用模块A中的函数时,在编

  • UML类图符号 类和对象的各种关系说明

    参考链接:Java对象与类之间的差异UML中描述对象和类之间相互关系的方式包括:依赖(Dependency),关联(Association),聚合(Aggregation),组合(Composition),泛化(Generalization),实现(Realization)等。  依赖(Dependency):元素A的变化会影响元素B,但反之不成立,那么B和A的关系是依赖关系,B依赖A;类属关系和实现关系在语义上讲也是依赖关系,但由于其有更特殊的用途,所以被单独描述。uml中用带箭头的虚线表示Dependency关系,箭头指向被依赖元素。 泛化(Generalization):通常所说的继承(特殊个体iskindof一般个体)关系,不必多解释了。uml中用带空心箭头的实线线表示Generalization关系,箭头指向一般个体。 实现(Realize):元素A定义一个约定,元素B实现这个约定,则B和A的关系是Realize,BrealizeA。这个关系最常用于接口。uml中用空心箭头和虚线表示Realize关系,箭头指向定义约定的元素。 关联(Association):元素间的结构化关

  • 复习 EL 表达式与 JSTL

    1.1EL表达式1.1.1概述  EL(ExpressionLanguage)是为了使JSP写起来更加简单。表达式语言的灵感来自于ECMAScript和XPath表达式语言,它提供了在JSP中简化表达式的方法,让JSP的代码更加简化。1.1.2EL表达式语法  EL表达式允许指定一个表达式来表示属性值。一个简单的表达式语法:${表达式}.EL中通用的操作符是.和{}。这两个操作符允许通过内嵌的JSP对象访问各种各样的JavaBean属性。注意:EL表达式的实质是从域中取值.示例<%-- CreatedbyIntelliJIDEA. User:Demo_Null Date:2020/6/23 Time:17:17 TochangethistemplateuseFile|Settings|FileTemplates. --%> <%@pagecontentType="text/html;charset=UTF-8"language="java"%> <%@pageimport="java.util.ArrayL

  • Python使用标准库zipfile+re提取docx文档中超链接文本和链接地址

    问题描述:WPS和OfficeWord创建的docx格式文档虽然格式大致相同,但还是有些细节的区别。例如,使用WPS创建的文档中如果包含超链接,可以使用“Python提取Word文档中所有超链接地址和文本”一文中介绍的技术和代码提取,但是同样的代码对于OfficeWord创建的docx文档无效。本文使用Python配合正则表达式来提取docx文档中的超链接文本和链接地址。 技术原理:假设有文件“带超链接的文档(Word版).docx”,内容如下,把该文件复制一份得到“带超链接的文档(Word版)-副本.docx”,修改扩展名为zip得到文件“带超链接的文档(Word版)-副本.zip”,打开该文件,结构如下, 进入word子文件夹,结构如下,双击文件document.xml,内容如下,方框内和箭头处是需要提取的内容,其中箭头处为资源ID,进入_rels文件夹,有如下文件, 双击打开文件“document.xml.rels,内容如下,红线处类似的地方是需要提取的信息, 参考代码: 运行结果:

  • 火热报名|腾讯企点邀您数字大会畅聊业务增长新动能

    腾讯产业互联网最重要的战略大会,腾讯全球数字生态大会火热预约中,下滑至文末直接报名!时间:9月9日到11日地点:线上主题:未来经济数字优先新冠肺炎疫情持续在全球蔓延,各国不得不采取各种隔离手段,造成经济活动的大幅缩减,凸显出全球化经济体系的物理脆弱性。因此,腾讯首倡“数字优先”。把“数字化”从局部、备选的位置,放到整体、首选的位置;从数据的生产、流转和价值生成的全流程,重塑产业能力。这次大会,腾讯产业互联网各业务板块负责人将透过屏幕,和大家谈谈腾讯产业互联网的年度战略,以及怎么实现“数字优先”。400多位国际知名经济学家、技术大牛、行业领军人物,也已经准备好聊聊数字经济发展的新趋势。大咖云集的未来经济峰会9月10号上午,未来经济峰会上线。腾讯公司董事会主席兼首席执行官马化腾将发来寄语。腾讯高级执行副总裁、云与智慧产业事业群总裁汤道生,腾讯副总裁、腾讯云总裁邱跃鹏,腾讯高级副总裁、腾讯广告和腾讯智慧零售负责人林璟骅,腾讯副总裁丁珂,腾讯副总裁钟翔平,腾讯微信事业群副总裁黄铁鸣,将分享腾讯产业互联网最新洞察、业务发展思路和各业务板块的最新实践成果。从最初的“开放平台”到“云”再到“产业互联

  • 前端开发:这10个Chrome扩展你不得不知

    转载请注明出处葡萄城为开发者提供专业的开发工具、解决方案和服务,赋能开发者。 原文出处:https://blog.bitsrc.io/10-top-chrome-extensions-for-front-end-developers-db23a01dce1e 1.CSSViewer这个工具在识别和显示元素的CSS属性方面很有用。它包括一个浮动窗口,您可以把鼠标悬停在页面上任一元素上以查看它的所有CSS属性。您可以通过快捷键在CSSViewer的窗体中轻松复制您选定元素的样式。也许您会感到奇怪,Chrome本身的开发者工具不是已经足够了吗,为什么我还要用它?其实这个插件比我们浏览器中的开发者工具显示的信息更多也更先进。除了基础的元素的宽度和高度的盒子模型外,还包括了所有已生效的样式及更多信息。2.AuguryAuury是由Rangle.io构建的DevTool扩展,用于调试、分析和优化Angular项目。Auury在DevTools中提供了丰富的UI,您可以:查看组件的依赖注入(DI)树图编辑及修改组件的属性发射事件等等…我个人认为,它在我想要了解组件的变更检测触发器可以沿着组件树向下延

  • WordPress网站插件装太多很卡怎么办?外贸网站加速方法

    网站装了太多插件速度慢怎么办?AssetCleanUp帮你优化速度用WordPress搭建的外贸网站通常都会安装几十个不同功能的插件,然后访问网站就会感觉速度比较慢,我们可以使用AssetCleanUp这款优化插件来帮忙让网站速度变得快一点。做GoogleSEO优化的朋友都知道,网站速度是影响搜索排名的一个因素,下面就跟着奶爸一起来使用AssetCleanUp优化下你网站的速度吧。1、安装AssetCleanUp安装AssetCleanUp的方法很简单,直接在WordPress后台搜索AssetCleanUp然后安装就可以了。2、安装完毕后我们启用。我们进入插件设置,需要先阅读Strippingthe“fat”,如下图:在页面最底下有一句“IunderstandhowthepluginworksandIwillmakesuretomakepropertests(via“TestMode”ifnecessary)afterthechangesI’mmaking.I’mawarethatunloadingthewrongCSS/JSfilescanbreakthelayoutandfron

  • 十分钟入门Nginx基本功能

    本文主要介绍一些Nginx的最基本功能以及简单配置,但不包括Nginx的安装部署以及实现原理。废话不多,直接开始。1、静态HTTP服务器首先,Nginx是一个HTTP服务器,可以将服务器上的静态文件(如HTML、图片)通过HTTP协议展现给客户端。 配置: server{ listen80;#端口号 location/{ root/usr/share/nginx/html;#静态文件路径 } }复制2、反向代理服务器什么是反向代理?客户端本来可以直接通过HTTP协议访问某网站应用服务器,如果网站管理员在中间加上一个Nginx,客户端请求Nginx,Nginx请求应用服务器,然后将结果返回给客户端,此时Nginx就是反向代理服务器。配置:server{ listen80; location/{ proxy_passhttp://192.168.20.1:8080;#应用服务器HTTP地址 } }复制既然服务器可以直接HTTP访问,为什么要在中间加上一个反向代理,不是多此一举吗?反向代理有什么作用?继续往下看,下面的负载均衡、虚拟主机,都基于反向代理实现,当然反向代理的功能也不仅仅是这些。

  • .Net语言 APP开发平台——Smobiler学习日志:手机应用的TextTabBar快速实现方式

    最前面的话:Smobiler是一个在VS环境中使用.Net语言来开发APP的开发平台,也许比Xamarin更方便一、目标样式我们要实现上图中的效果,需要如下的操作:1.从工具栏上的“SmobilerComponents”拖动一个TextTabBar控件到窗体界面上2.修改TextTabBar控件的属性a.BackColor属性设置控件的背景色为“White”,如图1;b.ForeColor属性设置控件字体的颜色,将该属性设置为“95,100,110”,表示RGB颜色,如图2;c.Items属性获得和设置标签栏单元集合,打开集合编辑器,并点击“添加”,分别填写Text(菜单项文本),Value(内部值,不在界面上显示),如图3、图4;图1图2图3图4d.ItemScroll属性设置是否允许标签栏滚动,将该属性设置为“True”,如图5;e.ItemScrollCount属性设置当ItemScroll属性为“True”时每次显示的单元数量,将该属性设置为“4”,如图6;f.Location属性让控件显示在合适的位置(0,16.5),如图7;g.SelectBackColor属性获取和设置标

  • 一个拯救微软帝国复兴的人-纳德拉

    T客汇官网:tikehui.com 原作者:AndrewNusca编译|李哲都柏林的秋日午后,狂风四起。飘忽而至的云驱散了落日的余晖,残余的灰色映衬在圣帕特里克学院学生们的脸上。他们慵懒地摆弄着手机,身后的十几个人,安静地坐在图书馆大厅里,有行政人员、老师和孩子们,他们在等待着一个人的到来。他就是西雅图的科技巨头,曾经在全球如日中天的微软公司CEO——萨提亚·纳德拉SatyaNadella。玻璃门打开了,纳德拉阔步而至,几位公司高管跟随在他身后。他和几位行政人员握了握手,径直走向等待他的孩子们。他和四位十岁左右的学生坐在一起,打听着他们的状况。一个男孩似乎很享受这场谈话,对着一个平板电脑指指点点,支支吾吾地解释着他在Minecraft的游戏世界里构建的三维世界(Minecraft是纳德拉上任以来的第一次大规模收购)。纳德拉笑容满面地回答他:“非常好,我需要一个这样的世界。”纳德拉站起身来。他足有六英尺高,瘦削的身材像长跑运动员,再加上他剃着光头,更加凸显出他紧绷的轮廓,显得他更高了。纳德拉每天早上跑步三十分钟,他更喜欢用跑步机,以免混凝土路面对他49岁的膝盖造成损伤。他十分珍惜自己的时

  • 司晓:“互联网+法治”引领中国弯道超车

     本文根据腾讯公共战略研究部总经理、腾讯研究院秘书长司晓在7月23日举办的“互联网+”时代的法治创新——第二届中国互联网法律政策论坛的发言整理。   各位好!能够从企业研究机构的视角,跟大家分享我们对“互联网+”与制度创新的看法,真是非常荣幸。先简单说说“互联网+”的缘起,2013年11月,腾讯董事会主席兼CEO马化腾先生在深圳出席WE大会发表题为“通向互联网未来的七个路标”的主题演讲时,系统阐述了“互联网+”的涵义。在今年“两会”提案里,马化腾在肯定“互联网+”促进传统产业的转型和升级方面发挥积极作用的同时,还提出“互联网+公共服务”以推进智慧民生建设,以及关注弱势群体、消除数字鸿沟以保障弱势群体也能获得新技术带来的红利等三方面的内容。  结合腾讯的“连接战略”,我们认为“互联网+”归根结底是要构建连接一切的新生态,具体可以从三个层面来理解。首先物理层面的连接,这是消除信息不对称的一个基础前提;其次化学意义上的连接,目的是创造一种新的价值增量;价值增量产生之后,才可以讲生物意义上的连接,最终是要形成一个新的生态分布体系,也就是把新的价值增量有序分布到新的生态链中,形成一种更加有序的新

  • PyQt 工程打包成exe之后获取当前路径出错问题处理

    平常写python代码,获取当前路径习惯用 os.path.realpath(os.path.dirname(__file__)) 复制 即通过python的__file__来判断脚本路径以此作为当前文件路径. 但是PyQt的代码通过pyinstaller打包的exe,再通过这种方式获取当前路径,获取出来的却是 C:\Users\Windows账号名\AppData\Local\Temp\_xxxx这样的路径. 打开这个路径,可以看到pyinstaller打包的exe它运行依赖的一些库文件都释放到了这个目录.我推测是打包exe时候,pyinstaller把可执行程序所需的库先打包进exe文件,在执行时候exe文件再把这些库文件释放到Temp文件夹下. 那怎么修复获取当前路径出错问题呢? 有两个方案: 1.通过sys.argv[0]的值来判断 os.path.realpath(os.path.dirname(sys.argv[0])) 复制 2.通过sys.executable的值来判断 os.path.realpath(os.path.dirname(sys.executable))

  • Java中Map集合的四种访问方式(转)

    最近学习Java发现集合类型真是很多,访问方式也很灵活,在网上找的方法,先放下备用     publicstaticvoidmain(String[]args){ Map<String,String>map=newHashMap<String,String>(); map.put("1","value1"); map.put("2","value2"); map.put("3","value3"); //第一种:普遍使用,二次取值 System.out.println("通过Map.keySet遍历key和value:"); for(Stringkey:map.keySet()){ System.out.println("key="+key+"andvalue="+map.get(key)); } //第二种 System.out.println("通过Map.entrySet使用iterator遍历key和value:"); Iterator<Map.Entry<String,String>>it=map.

  • 什么是 Linux 中的包管理器?它是如何工作的?

    最近更新时间2020年10月4日通过AbhishekPrakash  18条评论   Linux发行版之间的主要区别之一是包管理。在Linuxjargonbuster系列的这一部分中,您将了解Linux中的打包和包管理器。您将了解什么是包、什么是包管理器以及它们如何工作以及可用的包管理器类型。 Linux中的包管理器是什么? 简而言之,包管理器是一种允许用户在操作系统上安装、删除、升级、配置和管理软件包的工具。包管理器可以是像软件中心这样的图形应用程序,也可以是像apt-get或pacman这样的命令行工具。 你会经常发现我在It'sFOSS的教程和文章中使用了“包”这个词。要了解包管理器,您必须了解包是什么。 什么是包? 包通常指的是应用程序,但它可以是GUI应用程序、命令行工具或软件库(其他软件程序需要)。包本质上是一个存档文件,其中包含二进制可执行文件、配置文件,有时还包含有关依赖项的信息。 在过去,软件过去常常从其源代码安装。您将参考一个文件(通常命名为自述文件)并查看它需要哪些软件组件、二进制文件的位置。通常包括配置脚本或生成文件。您必须自己编

  • OSG 常用快捷键(全屏、查看帧数、截屏)

    一、全屏 #include<osgViewer/Viewer> #include<osgDB/ReadFile> #include<osgGA/GUIEventAdapter> #include<osgViewer/ViewerEventHandlers> intmain() { osg::ref_ptr<osgViewer::Viewer>view=newosgViewer::Viewer; osg::ref_ptr<osg::Node>node=newosg::Node; //node=osgDB::readNodeFile("glider.osg"); node=osgDB::readNodeFile("cow.osg"); view->addEventHandler(newosgViewer::WindowSizeHandler);//全屏快捷键f view->setSceneData(node); returnview->run(); }复制 二、查看帧数 #include&l

  • 几种响应式文字的玩法

    上一篇三种响应式文字未经过十分严谨地调查,错误颇多,于是在此篇重头来过。   讲真,其实我也不知道该如何为此篇开头, 因为响应式文字需不需要做其实我也没有深入探究过, 但在学习其他网站的过程中,我发现了一些比较新奇的做法,所以想试着梳理一下, 为何会出现这种有些奇怪,可能实则非常奇妙的解决方案。 如果理解有偏差的地方,还望大佬们不吝赐教。   简单来说,响应式是为了让网页在各种显示设备上都有不错的浏览体验, 无论是@media将元素换行,后台获取userAgent返回不同页面,利用viewport限定视图,还是利用根元素html属性来计算大小等, 他们都能实现各自编程特色的响应式布局,非要说谁是最优,恐怕还是得依需求而定。   接下来我们先大致罗列一下,这几种布局方法的如何施展的。   众所周知的Bootstrap,它的栅栏布局即为媒体查询的代表,完全通过屏宽来判断元素是否换行和是否显示。 <style>.col-xs-2{width:50%} @media(min-width:768px){ .col-sm-3{width:33.

  • 最详细的搭建个人博客教程

    前言 你是否也想拥有属于自己的博客?是否也想拥有跟我一样的博客空间?如果心动了,就赶紧往下看吧! 教程炒鸡简单,炒鸡详细,而且博客搭建完全是FreeofCharge! 原理 GithubPages Github不仅可以让我们把代码托管在平台上,而且允许我们利用Github的服务器部署自定义网页对我们的项目作简介。这个网页就被称为** GithubPages**。这是我们可以利用Github搭建免费博客的基础啦~ Hexo Hexo是一款轻量但高逼格的搭建博客快速工具,它是基于Node.js开发的。而Node.js...好了,扯远了...有兴趣的童鞋可以出门左转自己百度... 准备 知道了大致的原理,我们首先需要准备搭建博客的材料。如下: 1.一台windows系统的电脑 2.一个Github账号 3.安装Node.js 4.安装Git 5.安装Hexo 开始 申请Github账号,建立一个仓库,并为此创建一个说明网页(GithubPages) 假设我们都有了Github账号,这是首先在右上角点击“+”号,选择Newrepository 注意仓库名一定是"你的Github用户名"

  • 深入拆解Java虚拟机(三)JVM是如何执行方法调用的

      在Java程序里,如果同一个类中出现多个名字相同,并且参数类型相同的方法,那么它无法通过编译。也就是说,在正常情况下,如果我们想要在同一个类中定义名字相同的方法,那么它们的参数类型必须不同。这些方法之间的关系,我们称之为重载。   这个限制可以通过字节码工具绕开。也就是说,在编译完成之后,我们可以再向class文件中添加方法名和参数类型相同,而返回类型不同的方法。当这种包括多个方法名相同、参数类型相同,而返回类型不同的方法的类,出现在Java编译器的用户类路径上时,它是怎么确定需要调用哪个方法的呢?当前版本的Java编译器会直接选取第一个方法名以及参数类型匹配的方法。并且,它会根据所选取方法的返回类型来决定可不可以通过编译,以及需不需要进行值转换等。   重载的方法在编译过程中即可完成识别。具体到每一个方法调用,Java编译器会根据所传入参数的声明类型(注意与实际类型区分)来选取重载方法。选取的过程共分为三个阶段:   1.在不考虑对基本类型自动装拆箱(auto-boxing,auto-unboxing),以及可变长参数的情况下选取重载方法;   2.如果在第1个阶段中没有找到适配

  • 线性代数的本质-06-逆矩阵、列空间与零空间

    这几个部分学的还是蛮轻松的,再接再厉!继续加油~~~经过支干的整体介绍,这部分视频作者将会介绍逆矩阵(还原变换,后悔药)列空间(这是什么鬼?)秩(一个描述究竟有几维空间的东西)零空间(完全压缩的空间)。想要知道刚刚描述的是否正确,就继续听下去吧。 线性方程组 线性方程组的运算与矩阵的乘法看起来非常的类似,其本质是求解一个未知的向量,经过指定变换变换成为已知的向量。换句话描述,求解经过指定变换能够变换成已知向量的未知向量。视频作者描述:只考虑对空间变形,以及变换前后向量的重叠。 A逆,也即A的逆向变换,其核心性质是A-*A=E,是一个什么变换也没有做的矩阵,什么也没有做的变换称为恒等变换。 秩,变换后空间的维数。 Ax=v   矩阵的解依赖于矩阵A所代表的变换,矩阵A的变换分为两种情况:1.发生向低维空间的压缩2.没有发生向低维空间的压缩 当空间没有发生压缩时:这时有且仅有一个向量x能够在进行A变换后与向量v完全重合。(在这里引入A逆的概念,也即A的逆向变换),寻找向量x的过程为A-*v,描述为通过向量v的逆向变换过程寻找向量x。 当空间发生压缩时:此时不存在A逆。(可以

相关推荐

推荐阅读