用jad来反编译scala代码,看看版本是否是老版本:
1 | jad.exe -r -ff -d src -s java F:\class\**\*.class |
反编译的代码会在执行jad程序的目录src下
用jad来反编译scala代码,看看版本是否是老版本:
1 | jad.exe -r -ff -d src -s java F:\class\**\*.class |
反编译的代码会在执行jad程序的目录src下
前两天研究scala mongodb groupby的问题,又有了另外种解决方案:
在看driver core源码的时候 发现传入的表达式在encode的时候有如下判断:
1 | final class BuildersHelper { |
发现会判断value是否为Bson,那么想到Filter也是Bson类型,所以有了如下表达式:
1 | Filters.and(Filters.all("$code"),Filters.all("$userType")) |
今天同事问groupby多个字段是怎么写的
然后上$group (aggregation)
看了下,发现要写表达式,看了这篇文章MongoDB aggregate 运用篇 个人总结,发现要像如下写:
1 |
|
那么代码中应该怎么写呢,研究了半天,看到这篇文章MongoDB getCollection with a specific document class
发现我们得从定义mongodbClient开始定义个codeRegistry
1 |
|
然后在用的地方直接
1 | val groupBy = group(GroupByCode("$userType","$code"),sum("count", 1)) |
当然mongodb-scala-driver得升级到2.0版才支持caseClassCodec
New in 2.0, the Scala driver allows you to use case classes to represent documents in a collection via the Macros helper. Simple case classes and nested case classes are supported. Hierarchical modelling can be achieve by using a sealed trait and having case classes implement the parent trait.
在调用publishExternalAPI的时候注入的:
1 | angularModule('ng', ['ngLocale'], ['$provide', |
实际就是执行的1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
configFn参数会在调用的时候就执行
```js
//configFn有可能就是['$provide',function($provide){}]
//config 就是调用configBlocks[insertMethod || 'push']([provider, method, arguments]);
//这里的arguments就是configFn
if (configFn) {
config(configFn);
}
var config = invokeLater('$injector', 'invoke', 'push', configBlocks);
function invokeLater(provider, method, insertMethod, queue) {
if (!queue) queue = invokeQueue;
return function() {
queue[insertMethod || 'push']([provider, method, arguments]);
return moduleInstance;
};
}
queue就是configBlocks.
在runInvokeQueue中就会从providerInjector中获取$injector1
2
3
4
5
6
7
8
9
10
11function runInvokeQueue(queue) {
var i, ii;
for (i = 0, ii = queue.length; i < ii; i++) {
var invokeArgs = queue[i],
provider = providerInjector.get(invokeArgs[0]);//此处就是$injector
provider[invokeArgs[1]].apply(provider, invokeArgs[2]);
// invokeArgs[2]此处就是传入的参数数组
//['$provide',function ngModule($provide) {}]
}
}
providerCache在定义的时候就加入了$injector
1 | providerInjector = (providerCache.$injector = |
$injector在invoke参数数组的时候去providerCache里找到$provide并且调用它的provider方法1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23function invoke(fn, self, locals, serviceName) {
if (typeof locals === 'string') {
serviceName = locals;
locals = null;
}
//注入参数 $provide
var args = injectionArgs(fn, locals, serviceName);
if (isArray(fn)) { //比如['$scope',function($scope){}]
fn = fn[fn.length - 1];//取数组的最后一个
}
if (!isClass(fn)) {
// http://jsperf.com/angularjs-invoke-apply-vs-switch
// #5388
//比如 var injector = angular.injector(["myModule"]);
//injector.invoke(function(myService){alert(myService.my);});
return fn.apply(self, args);
} else {
args.unshift(null);
return new (Function.prototype.bind.apply(fn, args))();
}
}
上篇文章创建service最后我们提到了
$provide.service,也就是说模块调用service方法 其实内部到loadModules的时候通过runInvokeQueue
会调用内置的$provide.service函数。
比如我写了个方法如下:1
2
3
4var herModule = angular.module('herModule', []);
herModule.service('herService', function() {
this.her = 1;
});
我们一步步来分析它是怎么调用的,首先看第一步
我们在之前的文章依赖注入器的产生中看到createInjector的时候会把provideCache传入providerInjector,也就是说我们在调用1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
```js
function supportObject(delegate) {
return function(key, value) {
//当key是 对象的时候 就把delegate函数放入闭包里
if (isObject(key)) {
//reverseParams 为了适应foreach里调用函数的参数顺序
forEach(key, reverseParams(delegate));// function(value, key) {iteratorFn(key, value);};
} else {
//调用参数delegate方法
return delegate(key, value);
}
};
}
var providerCache = {
//supportObject 都返回一个新函数,内部调用service
$provide: {
service: supportObject(service),
//省略部分代码
}
}
$provide对象不止有service一个属性函数,supportObject 都返回一个新函数,内部调用service。
service函数内部其实就是调用factory函数1
2
3
4
5
6
7function service(name, constructor) {
//factoryFn就是个对象数组
return factory(name, ['$injector', function($injector) {
//实例化构造函数,返回实例
return $injector.instantiate(constructor);
}]);
}
factory函数内部又调用provider函数1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16//factoryFn有可能就是对象数组
//enforce代表是否要有返回值
function factory(name, factoryFn, enforce) {
return provider(name, {
$get: enforce !== false ? enforceReturnValue(name, factoryFn) : factoryFn
});
}
//返回一个有返回值的方法而已
function enforceReturnValue(name, factory) {
return function enforcedReturnValue() {
var result = instanceInjector.invoke(factory, this);
return result;
};
}
1 | function provider(name, provider_) { |
其中最终调用的就是provider方法把一开始的serviceName加上providerSuffix当作对象key,然后{$get:['$injector', function($injector) {return $injector.instantiate(constructor);}]}
放入了providerCache。