在这里,我们将给大家分享关于为什么无法从int到Long隐式转换?的知识,让您更了解无法从int*转换为int的本质,同时也会涉及到如何更有效地c–为什么不将clang或gcc标记为从double到i
在这里,我们将给大家分享关于为什么无法从int到Long隐式转换?的知识,让您更了解无法从int*转换为int的本质,同时也会涉及到如何更有效地c – 为什么不将clang或gcc标记为从double到int的隐式转换?、c – 为什么没有clang警告从double到int的隐式转换,但是从long到int时会这样做?、c – 从int到shared_ptr的隐式转换、c# – IntPtr允许从ulong到long的隐式转换的内容。
本文目录一览:- 为什么无法从int到Long隐式转换?(无法从int*转换为int)
- c – 为什么不将clang或gcc标记为从double到int的隐式转换?
- c – 为什么没有clang警告从double到int的隐式转换,但是从long到int时会这样做?
- c – 从int到shared_ptr的隐式转换
- c# – IntPtr允许从ulong到long的隐式转换
为什么无法从int到Long隐式转换?(无法从int*转换为int)
我可以隐式地将int转换为long,并将long转换为Long。为什么无法将int隐式转换为Long?为什么Java不能在示例的最后一行进行隐式转换?
int i = 10; //OKlong primitiveLong = i; //OKLong boxedLong = primitiveLong; //OKboxedLong = i; //Type mismatch: cannot convert from int to Long
答案1
小编典典Long
和Integer
是对象。装箱/拆箱仅适用于原语。做Long boxedLong = i
的就像Long boxedLong = newInteger(10)
,那不是不!另外,请记住,之间没有继承Long
,Integer
所以甚至Integer i = new Long()
无效
c – 为什么不将clang或gcc标记为从double到int的隐式转换?
void f(int x) { std::cout << x << std::endl; } int main() { double x = 1.5; f(x); return 0; }
这编译并运行时没有任何警告(使用-Wall),因此隐藏了从double到int的危险隐式转换.如果用文字调用函数,编译器将捕获强制转换,即
f(1.5)
但这并不是那么有用.为什么这些编译器没有为这个演员发出警告?我在OSX 10.8.3上使用gcc-4.2.1和clang-425.0.28.
解决方法
为了避免隐式转换,请使用-Wconversion标志(它不包含在-Wall中). Clang实际上在-Weverything标志中包含-Wconversion,但是这个标志比大多数用户习惯的警告要多得多.
c – 为什么没有clang警告从double到int的隐式转换,但是从long到int时会这样做?
#include <iostream> int main() { const long l = 4294967296; int i = l; return i; //just to silence the compiler }
编译器警告隐式转换(使用-Wall和-std = c 14)如下:
warning: implicit conversion from 'const long' to 'int' changes value from 4294967296 to 0 [-Wconstant-conversion]
没关系.但是如果转换是从double到int,则没有警告,如下面的代码所示:
#include <iostream> int main() { const double d = 4294967296.0; int i = d; return i; //just to silence the compiler }
为什么编译器在这些情况下会有不同的反应?
注1:clang版本为3.6.2-svn240577-1~exp1
注2:我已经使用Compiler Explorer(gcc.godbolt.org)测试了许多其他版本的gcc,clang和icc.因此,所有测试版本的gcc(除了5.x)和icc都会发出警告.没有clang版本做到了.
解决方法
从long int到int的转换可能或者可以工作或者可能是未定义的行为,具体取决于平台和值(唯一的保证是int不大于long int,但它们可能是相同的大小).
换句话说,整数类型之间的转换中的问题是实现的偶然工件,而不是设计决策.关于它们的警告更好,特别是如果在编译时可以检测到由于这些限制而无法正常工作.
另请注意,即使从double到int的转换也是合法且定义良好的(如果在边界内完成),即使在编译时可以看到精度损失,也不需要实现来警告它.编译器即使在使用可能有意义时也会发出太多警告可能是一个问题(你只是禁用警告,甚至更糟糕的是养成接受非正常构建的习惯).
这些隐含的转换规则可能与其他C皱纹相结合,变得真正奇怪且难以证明行为,例如:
std::string s; s = 3.141592654; // No warnings,no errors (last time I checked)
不要试图用C过多的逻辑.阅读规格效果更好.
c – 从int到shared_ptr的隐式转换
#include <iostream> #include <memory> void f(std::shared_ptr<int> sp) {} template <typename FuncType,typename PtrType> auto call_f(FuncType f,PtrType p) -> decltype(f(p)) { return f(p); } int main() { f(0); // doesn't work for any other int != 0,thanks @Rupesh // call_f(f,0); // error,cannot convert int to shared_ptr }
在main()的第一行中,整数0被转换为std :: shared_ptr< int>并且调用f(0)成功没有任何问题.但是,使用模板调用函数会使事情变得不同.第二行将不再编译,错误是
error: Could not convert 'p' from 'int' to 'std::shared_ptr<int>'
我的问题是:
>为什么第一次通话成功而第二次通话没有?这里有什么我想念的吗?
>我也不理解如何在调用f(0)中执行从int到std :: shared_ptr的转换,因为它看起来像std :: shared_ptr只有显式构造函数.
PS:这个例子的变体出现在Scott Meyers的Effective Modern C Item 8中,作为用nullptr保护这种调用的一种方式.
解决方法
A null pointer constant is an integral constant expression (5.19) prvalue of integer type that evaluates to zero or a prvalue of type
std::nullptr_t. A null pointer constant can be converted to a
pointer type; the result is the null pointer value of that type and is
distinguishable from every other value of object pointer or function
pointer type. Such a conversion is called a null pointer conversion.
Two null pointer values of the same type shall compare equal. The
conversion of a null pointer constant to a pointer to cv-qualified
type is a single conversion,and not the sequence of a pointer
conversion followed by a qualification conversion (4.4). A null
pointer constant of integral type can be converted to a prvalue of
type std::nullptr_t. [ Note: The resulting prvalue is not a null
pointer value. —end note ]
在第二种情况下,p被推导为类型int,虽然值为零但不再是空指针常量,因此不适合相同的情况.
作为T.C.指出措辞已经改变了DR 903,这需要一个零值为零的整数文字而不是一个计算为零的整数常量表达式:
A null pointer constant is an integer literal (2.14.2) with value zero or a prvalue of type std::nullptr_t. A null pointer constant can be converted to a pointer type; the result is the null pointer value of that type and is distinguishable from every other value of object pointer or function pointer type.
c# – IntPtr允许从ulong到long的隐式转换
class A { public static explicit operator A(long mm) { return null; } } UInt64 ul = UInt64.MaxValue; IntPtr ptr = (IntPtr)ul;//no error A a = (A)ul;//Cannot convert type 'ulong' to 'A'
为什么IntPtr允许这种行为?
以下是IL代码:
.entrypoint .maxstack 1 .locals init ( [0] uint64 ul,[1] native int ptr) L_0000: nop L_0001: ldc.i4.m1 L_0002: conv.i8 L_0003: stloc.0 L_0004: ldloc.0 L_0005: call native int [mscorlib]system.intPtr::op_Explicit(int64) L_000a: stloc.1 L_000b: ret
解决方法
测试#1:做一个ulong和long的演员
ulong ul = UInt64.MaxValue; long l = Int64.MaxValue; IntPtr ulptr = (IntPtr)ul; IntPtr lptr = (IntPtr)l;
因为IntPtr转换声明它可能抛出OverflowException,所以我期待(IntPtr)ul强制抛出异常.它没.想象一下,当(IntPtr)l cast抛出一个OverflowException时我会感到惊讶.看看这个,我看到我的项目设置为x86编译,所以异常现在有意义 – Int64.MaxValue太大而不适合32位IntPtr.
测试#2:在相同的代码周围放置一个选中的块.
现在,我真的希望(IntPtr)ul强制抛出异常,它确实如此.
这让我想知道第一次演员是怎么回事.在未经检查的代码上使用ildasm会导致以下结果:
IL_0000: nop IL_0001: ldc.i4.m1 IL_0002: conv.i8 IL_0003: stloc.0 IL_0004: ldc.i8 0x7fffffffffffffff IL_000d: stloc.1 IL_000e: ldloc.0 IL_000f: call native int [mscorlib]system.intPtr::op_Explicit(int64) IL_0014: stloc.2 IL_0015: ldloc.1 IL_0016: call native int [mscorlib]system.intPtr::op_Explicit(int64)
因此-1被放在堆栈上并转换为int64,但是没有从unsigned到signed int64的额外转换.
选中的版本略有不同:
IL_0000: nop IL_0001: nop IL_0002: ldc.i4.m1 IL_0003: conv.i8 IL_0004: stloc.0 IL_0005: ldc.i8 0x7fffffffffffffff IL_000e: stloc.1 IL_000f: ldloc.0 IL_0010: conv.ovf.i8.un IL_0011: call native int [mscorlib]system.intPtr::op_Explicit(int64) IL_0016: stloc.2 IL_0017: ldloc.1 IL_0018: call native int [mscorlib]system.intPtr::op_Explicit(int64)
现在有一个从unsigned到signed的转换,这在溢出的情况下是必要的.
不幸的是,这并没有回答原来的问题.
更新:我删除了不正确的答案部分,因此没有留下任何实际答案.但是,我希望它有用,所以我没有删除整个答案.
关于为什么无法从int到Long隐式转换?和无法从int*转换为int的介绍已经告一段落,感谢您的耐心阅读,如果想了解更多关于c – 为什么不将clang或gcc标记为从double到int的隐式转换?、c – 为什么没有clang警告从double到int的隐式转换,但是从long到int时会这样做?、c – 从int到shared_ptr的隐式转换、c# – IntPtr允许从ulong到long的隐式转换的相关信息,请在本站寻找。
在本文中,我们将带你了解ActivityCompat.requestPermissions不显示提示在这篇文章中,同时我们还将给您一些技巧,以帮助您实现更有效的ActivitiException: Activiti database problem: Tables missing for component(s) identity、Activity、AppCompatActivity、FragmentActivity 和 ActionBarActivity:什么时候使用?、An application is attempting to perform an action that requires privileges. Authentication is requir、Android Java无法在片段中显示requestPermission。
本文目录一览:- ActivityCompat.requestPermissions不显示提示
- ActivitiException: Activiti database problem: Tables missing for component(s) identity
- Activity、AppCompatActivity、FragmentActivity 和 ActionBarActivity:什么时候使用?
- An application is attempting to perform an action that requires privileges. Authentication is requir
- Android Java无法在片段中显示requestPermission
ActivityCompat.requestPermissions不显示提示
我正在尝试请求ACCESS_FINE_LOCATION
权限以获取用户的当前位置。
我的日志记录表明,在查询ContextCompat.checkSelfPermission()
时,我的应用当前没有此权限,但是在不调用ActivityCompat.requestPermissions()
任何内容时,则显示。
我的Google地图代码(实现OnMapReadyCallback
和ActivityCompat.OnRequestPermissionsResultCallback()
)位于中FragmentActivity
。
我设法使该requestPermissions()
功能在该应用程序的其他“活动”中成功运行,这只是带有Google地图的功能。将其放在或中的onCreate()
方法Activity
中onMapReady()
(它需要去的地方),该方法不起作用。
if(ContextCompat.checkSelfPermission(LocationActivity.this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { Log.d(TAG, "not granted"); final String[] permissions = new String[] {android.Manifest.permission.ACCESS_FINE_LOCATION}; if(ActivityCompat.shouldShowRequestPermissionRationale(this, android.Manifest.permission.ACCESS_FINE_LOCATION)) { Log.d(TAG, "rationale"); // Explain to the user why permission is required, then request again AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setMessage("We need permissions") .setCancelable(false) .setPositiveButton("OK", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { ActivityCompat.requestPermissions(LocationActivity.this, permissions, 1); } }); AlertDialog alert = builder.create(); alert.show(); } else { Log.d(TAG, "request" + android.Manifest.permission.ACCESS_FINE_LOCATION); // If permission has not been denied before, request the permission ActivityCompat.requestPermissions(LocationActivity.this, permissions, 1); }} else { Log.d(TAG, "granted");}
有任何想法吗?这与我的Activity的类(FragmentActivity
)有关,还是与Google地图异步调用权限请求有关?
答案1
小编典典在完全删除我的类并且仍然无法正常工作之后,我意识到此Activity是使用TabHost实例化的。
当我停止使用TabHost时,提示会成功显示。我猜新的权限提示不支持TabHosts-这是一个错误吗?
我最终创建了一个PermissionsRequestActivity,它代表我的TabHost处理许可请求和响应,然后退出(通过Intent
extras捆绑包传递请求的许可信息)。
它将响应以广播的形式传递回请求,由我的TabHost接收。
有点破解,但工作正常!
ActivitiException: Activiti database problem: Tables missing for component(s) identity
报错信息:
Caused by: org.activiti.engine.ActivitiException: Activiti database problem: Tables missing for component(s) identity
at org.activiti.engine.impl.db.DbSqlSession.dbSchemaCheckVersion(DbSqlSession.java:886)
at org.activiti.engine.impl.db.DbSqlSession.performSchemaOperationsProcessEngineBuild(DbSqlSession.java:1360)
原因是数据库中缺少 activiti 用的 ACT_ID_* 的表。 可以从 activiti 的 jar 包中解压出建表 sql。
Activity、AppCompatActivity、FragmentActivity 和 ActionBarActivity:什么时候使用?
我来自 iOS,这很容易,您只需使用 UIViewController。然而,在 Android 中,事情似乎要复杂得多,某些 UIComponents
用于特定的 API 级别。我正在阅读适用于 Android 的 BigNerdRanch(这本书大约有 2
年的历史),他们建议我用它Activity
来托管我的FragmentActivities
. 但是,我认为Activity
已弃用。
那么对于 API 级别 22(至少支持 API 级别 15 或
16),我究竟应该使用什么来托管组件和组件本身?所有这些都有用吗,还是我应该几乎只使用一两个?
答案1
小编典典我认为 Activity 已被弃用
不。
那么对于 API 级别 22(至少支持 API 级别 15 或
16),我究竟应该使用什么来托管组件和组件本身?所有这些都有用吗,还是我应该几乎只使用一两个?
Activity
是基线。Activity
每个活动都直接或间接地继承自。
FragmentActivity
用于support-v4
和support-v13
库中找到的片段的反向移植。在 API 级别 11
中添加了片段的本机实现,低于您的建议minSdkVersion
值。您需要特别考虑的唯一原因FragmentActivity
是您是否要使用嵌套片段(一个片段包含另一个片段),因为在
API 级别 17 之前,本机片段不支持这一点。
AppCompatActivity
来自appcompat-v7
图书馆。原则上,这提供了操作栏的反向移植。由于本机操作栏是在 API 级别 11
中添加的,因此您不需要这样做AppCompatActivity
。但是,就操作栏和各种小部件而言,当前版本appcompat-v7
还添加了
Material Design 美学的有限反向移植。使用 的优点和缺点appcompat-v7
远远超出了这个特定的 Stack Overflow
答案的范围。
ActionBarActivity
是来自
的基础活动的旧名称appcompat-v7
。由于种种原因,他们想改名。除非您使用的某些第三方库坚持使用ActionBarActivity
,否则您应该更AppCompatActivity
喜欢ActionBarActivity
.
因此,鉴于您minSdkVersion
在 15-16 范围内:
如果您想要向后移植的 Material Design 外观,请使用
AppCompatActivity
如果不是,但您想要嵌套片段,请使用
FragmentActivity
如果没有,请使用
Activity
只需从注释中添加注释:AppCompatActivity
extendsFragmentActivity
,因此任何需要使用功能的人FragmentActivity
都可以使用AppCompatActivity
。
An application is attempting to perform an action that requires privileges. Authentication is requir
An application is attempting to perform an action that requires privileges. Authentication is required to perform this action.
resolve : sudo command...
Android Java无法在片段中显示requestPermission
首先,我想指出一个错字: getCurrentLocaiton();
除此之外:
可能是您的背景吗?我的意思是,如果问题仅是拼写错误,那么这是完全不相关的,请首先解决该问题。
getApplicationContext()引用整个应用程序上下文。
替代方法是getContext(),它引用您所在的特定视图。
我正在阅读有关内容,发现了一些有用的信息。 https://developer.android.com/training/permissions/requesting //您需要在上下文中请求的部分。
然后我读到以下内容: Difference between getContext(),getApplicationContext(),getBaseContext() and "this"
由于您位于片段中,因此您可能需要在片段中请求权限。
今天关于ActivityCompat.requestPermissions不显示提示的介绍到此结束,谢谢您的阅读,有关ActivitiException: Activiti database problem: Tables missing for component(s) identity、Activity、AppCompatActivity、FragmentActivity 和 ActionBarActivity:什么时候使用?、An application is attempting to perform an action that requires privileges. Authentication is requir、Android Java无法在片段中显示requestPermission等更多相关知识的信息可以在本站进行查询。
对于想了解Action Bar Sherlock 4标题文字的颜色-我在哪里出错?的读者,本文将是一篇不可错过的文章,并且为您提供关于action bar 怎么去掉标题文字、ActionBarSherlock — 无缝集成ActionBar、actionbarsherlock 导入有错误、actionbarsherlock 心得的有价值信息。
本文目录一览:- Action Bar Sherlock 4标题文字的颜色-我在哪里出错?
- action bar 怎么去掉标题文字
- ActionBarSherlock — 无缝集成ActionBar
- actionbarsherlock 导入有错误
- actionbarsherlock 心得
Action Bar Sherlock 4标题文字的颜色-我在哪里出错?
我在使操作栏标题文本颜色变为白色时遇到困难。遵循示例,我相信我的代码是正确的,但是文本显示为黑色。
谁能看到我做错了吗?
<resources> <style name="Theme.MyApp" parent="Theme.Sherlock.Light"> <item name="actionBarStyle">@style/Widget.MyApp.ActionBar</item> <item name="android:actionBarStyle">@style/Widget.MyApp.ActionBar</item> <item name="titleTextStyle">@style/Widget.MyApp.TitleTextStyle</item> <item name="android:titleTextStyle">@style/Widget.MyApp.TitleTextStyle</item> </style> <style name="Widget.MyApp.ActionBar" parent="Widget.Sherlock.Light.ActionBar"> <item name="background">@drawable/gradient_blue</item> <item name="android:background">@drawable/gradient_blue</item> </style> <style name="Widget.MyApp.TitleTextStyle" parent="Widget.Sherlock.Light.ActionBar"> <item name="titleTextStyle">@color/white</item> <item name="android:titleTextStyle">@color/white</item> </style></resources>
提前谢谢了!
答案1
小编典典使用以下内容,只需自定义actionBarStyle
属性:
<resources> <style name="Theme.MyApp" parent="Theme.Sherlock.Light"> <item name="actionBarStyle">@style/Widget.MyApp.ActionBar</item> <item name="android:actionBarStyle">@style/Widget.MyApp.ActionBar</item> </style> <style name="Widget.MyApp.ActionBar" parent="Widget.Sherlock.Light.ActionBar"> <item name="titleTextStyle">@style/Widget.MyApp.TitleTextStyle</item> <item name="android:titleTextStyle">@style/Widget.MyApp.TitleTextStyle</item> </style> <style name="Widget.MyApp.TitleTextStyle" parent="TextAppearance.Sherlock.Widget.ActionBar.Title"> <item name="android:textColor">@color/white</item> </style></resources>
您也可以自定义textSize
标题。
action bar 怎么去掉标题文字
问怎么去掉 标题栏的 “例子” 两字 ,我试过了 代码方式 ,但是在开启应用的时候有短暂的停留 ,闪烁 。不符合要求,请问怎么设置 或者 xml的方式去掉 。
ActionBarSherlock — 无缝集成ActionBar
如果你想在3.0+系统上使用系统的ActionBar而在3.0以前的系统上使用自定义的ActionBar,那么ActionBarSherlock就可以帮助你了.
ActionBarSherlock 是Android compatibility library 的一个扩展, 不知道什么原因 Android 兼容开发包没有包含ActionBar. 所以就有了ActionBarSherlock . 其使用方式和 兼容开发包类似.
下载地址: https://github.com/JakeWharton/ActionBarSherlock/zipball/3.4.2
有两种方式把ActionBarSherlock类库引入到你的项目中,:
- 使用Eclipse和ADT插件.
- 使用Maven.
<dependency> <groupId>com.actionbarsherlock</groupId> <artifactId>library</artifactId> <version>3.4.2</version> <type>apklib</type> </dependency>
android.support.v4.app.ActionBar android.support.v4.view.Menu android.support.v4.view.MenuItem
这些类的名称和3.0系统中的一样.

使用原生ActionBar

使用自定义ActionBar
actionbarsherlock 导入有错误
有用actionbarsherlock的前辈么, 这个问题遇到过么?我在公司电脑上导入actionbarsherlock一定问题也没有,回家就这样,是怎么回事啊? 环境都是一样的。
actionbarsherlock 心得
主要方法,就是标题栏菜单的设置
@Override @Override public boolean onOptionsItemSelected(MenuItem item) { } break; return false; |
分清楚 SherlockFragmentActivity SherlockFragment 并且按照 DEMO 配合使用
关于Action Bar Sherlock 4标题文字的颜色-我在哪里出错?的介绍现已完结,谢谢您的耐心阅读,如果想了解更多关于action bar 怎么去掉标题文字、ActionBarSherlock — 无缝集成ActionBar、actionbarsherlock 导入有错误、actionbarsherlock 心得的相关知识,请在本站寻找。
在这篇文章中,我们将带领您了解MongoFactoryBean和SimpleMongoDbFactory之间的区别的全貌,包括mongorepository和mongotemplate的相关情况。同时,我们还将为您介绍有关Activiti的BeanFactory和FactoryBean的区别、BeanFactory 和FactoryBean的区别、BeanFactory 简介以及它 和FactoryBean的区别、BeanFactory与FactoryBean的区别的知识,以帮助您更好地理解这个主题。
本文目录一览:- MongoFactoryBean和SimpleMongoDbFactory之间的区别(mongorepository和mongotemplate)
- Activiti的BeanFactory和FactoryBean的区别
- BeanFactory 和FactoryBean的区别
- BeanFactory 简介以及它 和FactoryBean的区别
- BeanFactory与FactoryBean的区别
MongoFactoryBean和SimpleMongoDbFactory之间的区别(mongorepository和mongotemplate)
我正在设置一个MongoDB Spring MVC应用程序,并尝试使用Service,DAO模式。
我在这里阅读了Spring-Data-
MongoDB参考,但我不了解MongoFactoryBean和SimpleMongoDbFactory之间的区别是什么。
什么是创建MongoTemplate bean的更好方法,为什么?
@Configurationpublic class SpringMongoConfig { public @Bean MongoDbFactory mongoDbFactory() throws Exception { return new SimpleMongoDbFactory(new MongoClient(), "yourdb"); } public @Bean MongoTemplate mongoTemplate() throws Exception { MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory()); return mongoTemplate; }}
要么。
@Beanpublic MongoFactoryBean mongo() { MongoFactoryBean mongo = new MongoFactoryBean(); mongo.setHost(env.getProperty("db.host")); mongo.setPort(env.getProperty("db.port",Integer.class,27017)); return mongo;}@Beanpublic MongoTemplate mongoTemplate() throws Exception{ return new MongoTemplate(mongo().getObject(),env.getProperty("db.name"));}
什么时候使用MongoFactoryBean,什么时候使用MongoDbFactory?他们有不同的用例吗?
同样,将MongoDB高度可伸缩和可配置的最佳方式是将MongoDB引导到Spring
MVC中,并且还提供了插入任何其他RDBMS(具有相同或不同功能)的条件。(也许有两种不同的DAO代表各种DB类型?)
答案1
小编典典我很惊讶这个问题仍然没有得到回答。尽管这可能不是您要找的确切答案,但这是我的看法。我发现使用第二种方法MongoFactoryBean
最好。
仅仅是因为有更多的配置选项。例如,如果您想设置一个Exception Translator,则可以使用轻松实现MongoFactoryBean
。
如果我没记错的话,但我可能是错的,MongoFactoryBean是为了方便起见MongoDbFactory
。意思是,它增加了另一层抽象。
总之,采用第二种方法。
Activiti的BeanFactory和FactoryBean的区别
1.
BeanFactory是Ioc的最基本的形式,Spring对其的实现有很多XMLBeanfactory....,是个Factory,也就是ioc容器和对象工厂
对于FacotryBean来说就是一个Bean,在Spring中,BeanFactory对所以的Bean进行·管理,而对于FactoryBean来说,并不是要一个简单的Bean,而是一个能生产和修饰对象生成的工厂Bean
processEngine Class:org.activiti.spring.ProcessEngineFactoryBean
在ProcessEngineFactoryBean中,持有AplicationContext, processEngine, processEngineConfigurationImpl对象,FactoryBean返回的不是一个实力bean,而是有runtimeService方法返回的一个实例Bean
BeanFactory 和FactoryBean的区别
BeanFacotry是spring中比较原始的Factory。如XMLBeanFactory就是一种典型的BeanFactory。原始的BeanFactory无法支持spring的许多插件,如AOP功能、Web应用等。
ApplicationContext接口,它由BeanFactory接口派生而来,ApplicationContext包含BeanFactory的所有功能,通常建议比BeanFactory优先
BeanFactory和FactoryBean的区别
BeanFactory是接口,提供了OC容器最基本的形式,给具体的IOC容器的实现提供了规范,
FactoryBean也是接口,为IOC容器中Bean的实现提供了更加灵活的方式,FactoryBean在IOC容器的基础上给Bean的实现加上了一个简单工厂模式和装饰模式(如果想了解装饰模式参考:修饰者模式(装饰者模式,Decoration) 我们可以在getObject()方法中灵活配置。其实在Spring源码中有很多FactoryBean的实现类.
区别:BeanFactory是个Factory,也就是IOC容器或对象工厂,FactoryBean是个Bean。在Spring中,所有的Bean都是由BeanFactory(也就是IOC容器)来进行管理的。但对FactoryBean而言,这个Bean不是简单的Bean,而是一个能生产或者修饰对象生成的工厂Bean,它的实现与设计模式中的工厂模式和修饰器模式类似
1、 BeanFactory
BeanFactory,以Factory结尾,表示它是一个工厂类(接口), 它负责生产和管理bean的一个工厂。在Spring中,BeanFactory是IOC容器的核心接口,它的职责包括:实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。BeanFactory只是个接口,并不是IOC容器的具体实现,但是Spring容器给出了很多种实现,如 DefaultListableBeanFactory、XmlBeanFactory、ApplicationContext等,其中XmlBeanFactory就是常用的一个,该实现将以XML方式描述组成应用的对象及对象间的依赖关系。XmlBeanFactory类将持有此XML配置元数据,并用它来构建一个完全可配置的系统或应用。
都是附加了某种功能的实现。 它为其他具体的IOC容器提供了最基本的规范,例如DefaultListableBeanFactory,XmlBeanFactory,ApplicationContext 等具体的容器都是实现了BeanFactory,再在其基础之上附加了其他的功能。
BeanFactory和ApplicationContext就是spring框架的两个IOC容器,现在一般使用ApplicationnContext,其不但包含了BeanFactory的作用,同时还进行更多的扩展。
BeanFacotry是spring中比较原始的Factory。如XMLBeanFactory就是一种典型的BeanFactory。
原始的BeanFactory无法支持spring的许多插件,如AOP功能、Web应用等。ApplicationContext接口,它由BeanFactory接口派生而来,
ApplicationContext包含BeanFactory的所有功能,通常建议比BeanFactory优先
ApplicationContext以一种更向面向框架的方式工作以及对上下文进行分层和实现继承,ApplicationContext包还提供了以下的功能:
• MessageSource, 提供国际化的消息访问
• 资源访问,如URL和文件
• 事件传播
• 载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的web层;
在不使用spring框架之前,我们的service层中要使用dao层的对象,不得不在service层中new一个对象。存在的问题:层与层之间的依赖。
service层要用dao层对象需要配置到xml配置文件中,至于对象是怎么创建的,关系是怎么组合的都交给了spring框架去实现。
[Java] 纯文本查看 复制代码
?
1
2
1 Resource resource = new FileSystemResource("beans.xml");
2 BeanFactory factory = new XmlBeanFactory(resource);
[Java] 纯文本查看 复制代码
?
1
2
1 ClassPathResource resource = new ClassPathResource("beans.xml");
2 BeanFactory factory = new XmlBeanFactory(resource);
[Java] 纯文本查看 复制代码
?
1
2
1 ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"applicationContext.xml", "applicationContext-part2.xml"});
3 BeanFactory factory = (BeanFactory) context;
基本就是这些了,接着使用getBean(String beanName)方法就可以取得bean的实例;BeanFactory提供的方法及其简单,仅提供了六种方法供客户调用:
boolean containsBean(String beanName) 判断工厂中是否包含给定名称的bean定义,若有则返回true
Object getBean(String) 返回给定名称注册的bean实例。根据bean的配置情况,如果是singleton模式将返回一个共享实例,否则将返回一个新建的实例,如果没有找到指定bean,该方法可能会抛出异常
Object getBean(String, Class) 返回以给定名称注册的bean实例,并转换为给定class类型
Class getType(String name) 返回给定名称的bean的Class,如果没有找到指定的bean实例,则排除NoSuchBeanDefinitionException异常
boolean isSingleton(String) 判断给定名称的bean定义是否为单例模式
String[] getAliases(String name) 返回给定bean名称的所有别名
[Java] 纯文本查看 复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
package org.springframework.beans.factory;
import org.springframework.beans.BeansException;
public interface BeanFactory {
String FACTORY_BEAN_PREFIX = "&";
Object getBean(String name) throws BeansException;
<T> T getBean(String name, Class<T> requiredType) throws BeansException;
<T> T getBean(Class<T> requiredType) throws BeansException;
Object getBean(String name, Object... args) throws BeansException;
boolean containsBean(String name);
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
boolean isTypeMatch(String name, Class<?> targetType) throws NoSuchBeanDefinitionException;
Class<?> getType(String name) throws NoSuchBeanDefinitionException;
String[] getAliases(String name);
}
2、FactoryBean
一般情况下,Spring通过反射机制利用<bean>的class属性指定实现类实例化Bean,在某些情况下,实例化Bean过程比较复杂,如果按照传统的方式,则需要在<bean>中提供大量的配置信息。配置方式的灵活性是受限的,这时采用编码的方式可能会得到一个简单的方案。Spring为此提供了一个org.springframework.bean.factory.FactoryBean的工厂类接口,用户可以通过实现该接口定制实例化Bean的逻辑。FactoryBean接口对于Spring框架来说占用重要的地位,Spring自身就提供了70多个FactoryBean的实现。它们隐藏了实例化一些复杂Bean的细节,给上层应用带来了便利。从Spring3.0开始,FactoryBean开始支持泛型,即接口声明改为FactoryBean<T>的形式
以Bean结尾,表示它是一个Bean,不同于普通Bean的是:它是实现了FactoryBean<T>接口的Bean,根据该Bean的ID从BeanFactory中获取的实际上是FactoryBean的getObject()返回的对象,而不是FactoryBean本身,如果要获取FactoryBean对象,请在id前面加一个&符号来获取。
例如自己实现一个FactoryBean,功能:用来代理一个对象,对该对象的所有方法做一个拦截,在调用前后都输出一行LOG,模仿ProxyFactoryBean的功能。
[Java] 纯文本查看 复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
/**
* my factory bean<p>
* 代理一个类,拦截该类的所有方法,在方法的调用前后进行日志的输出
* @author daniel.zhao
*
*/
public class MyFactoryBean implements FactoryBean<Object>, InitializingBean, DisposableBean {
private static final Logger logger = LoggerFactory.getLogger(MyFactoryBean.class);
private String interfaceName;
private Object target;
private Object proxyObj;
@Override
public void destroy() throws Exception {
logger.debug("destroy......");
}
@Override
public void afterPropertiesSet() throws Exception {
proxyObj = Proxy.newProxyInstance(
this.getClass().getClassLoader(),
new Class[] { Class.forName(interfaceName) },
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
logger.debug("invoke method......" + method.getName());
logger.debug("invoke method before......" + System.currentTimeMillis());
Object result = method.invoke(target, args);
logger.debug("invoke method after......" + System.currentTimeMillis());
return result; }
});
logger.debug("afterPropertiesSet......");
}
@Override
public Object getObject() throws Exception {
logger.debug("getObject......");
return proxyObj;
}
@Override
public Class<?> getObjectType() {
return proxyObj == null ? Object.class : proxyObj.getClass();
}
@Override
public boolean isSingleton() {
return true;
}
public String getInterfaceName() {
return interfaceName;
}
public void setInterfaceName(String interfaceName) {
this.interfaceName = interfaceName;
}
public Object getTarget() {
return target;
}
public void setTarget(Object target) {
this.target = target;
}
public Object getProxyObj() {
return proxyObj;
}
public void setProxyObj(Object proxyObj) {
this.proxyObj = proxyObj;
}/alignXML-Bean配置如下
}
[XML] 纯文本查看 复制代码
?
1 <bean id="fbHelloWorldService">
2 <property name="interfaceName" value="com.ebao.xxx.HelloWorldService" />
3 <property name="target" ref="helloWorldService" />
4 </bean>
Junit Test class
[Java] 纯文本查看 复制代码
?
@RunWith(JUnit4ClassRunner.class)
@ContextConfiguration(classes = { MyFactoryBeanConfig.class })
public class MyFactoryBeanTest {
@Autowired
private ApplicationContext context;
/**
* 测试验证FactoryBean原理,代理一个servcie在调用其方法的前后,打印日志亦可作其他处理
* 从ApplicationContext中获取自定义的FactoryBean
* context.getBean(String beanName) ---> 最终获取到的Object是FactoryBean.getObejct(),
* 使用Proxy.newInstance生成service的代理类
*/
@Test
public void testFactoryBean() {
HelloWorldService helloWorldService = (HelloWorldService) context.getBean("fbHelloWorldService");
helloWorldService.getBeanName();
helloWorldService.sayHello();
}
}
FactoryBean是一个接口,当在IOC容器中的Bean实现了FactoryBean后,通过getBean(String BeanName)获取到的Bean对象并不是FactoryBean的实现类对象,而是这个实现类中的getObject()方法返回的对象。要想获取FactoryBean的实现类,就要getBean(&BeanName),在BeanName之前加上&。
Java代码
[Java] 纯文本查看 复制代码
?
package org.springframework.beans.factory;
public interface FactoryBean<T> {
T getObject() throws Exception;
Class<?> getObjectType();
boolean isSingleton();
}
在该接口中还定义了以下3个方法:
TgetObject():返回由FactoryBean创建的Bean实例,如果isSingleton()返回true,则该实例会放到Spring容器中单实例缓存池中;
booleanisSingleton():返回由FactoryBean创建的Bean实例的作用域是singleton还是prototype;
Class<T>getObjectType():返回FactoryBean创建的Bean类型。
当配置文件中<bean>的class属性配置的实现类是FactoryBean时,通过getBean()方法返回的不是FactoryBean本身,而是FactoryBean#getObject()方法所返回的对象,相当于FactoryBean#getObject()代理了getBean()方法。
例:如果使用传统方式配置下面Car的<bean>时,Car的每个属性分别对应一个<property>元素标签。
[Java] 纯文本查看 复制代码
?
package com.baobaotao.factorybean;
public class Car {
private int maxSpeed ;
private String brand ;
private double price ;
public int getMaxSpeed () {
return this . maxSpeed ;
}
public void setMaxSpeed ( int maxSpeed ) {
this . maxSpeed = maxSpeed;
}
public String getBrand () {
return this . brand ;
}
public void setBrand ( String brand ) {
this . brand = brand;
}
public double getPrice () {
return this . price ;
}
public void setPrice ( double price ) {
this . price = price;
}
}
如果用FactoryBean的方式实现就灵活点,下例通过逗号分割符的方式一次性的为Car的所有属性指定配置值:
[Java] 纯文本查看 复制代码
?
package com.baobaotao.factorybean;
import org.springframework.beans.factory.FactoryBean;
public class CarFactoryBean implements FactoryBean<Car> {
private String carInfo ;
public Car getObject () throws Exception {
Car car = new Car () ;
String [] infos = carInfo .split ( "," ) ;
car.setBrand ( infos [ 0 ]) ;
car.setMaxSpeed ( Integer. valueOf ( infos [ 1 ])) ;
car.setPrice ( Double. valueOf ( infos [ 2 ])) ;
return car;
}
public Class<Car> getObjectType () {
return Car. class ;
}
public boolean isSingleton () {
return false ;
}
public String getCarInfo () {
return this . carInfo ;
}
// 接受逗号分割符设置属性信息
public void setCarInfo ( String carInfo ) {
this . carInfo = carInfo;
}
}
有了这个CarFactoryBean后,就可以在配置文件中使用下面这种自定义的配置方式配置CarBean了:
[XML] 纯文本查看 复制代码
?
<bean d="car"
P:carInfo="法拉利,400,2000000"/>
当调用getBean("car")时,Spring通过反射机制发现CarFactoryBean实现了FactoryBean的接口,这时Spring容器就调用接口方法CarFactoryBean#getObject()方法返回。如果希望获取CarFactoryBean的实例,则需要在使用getBean(beanName)方法时在beanName前显示的加上"&"前缀:如getBean("&car");
下面是一个应用FactoryBean的例子
[XML] 纯文本查看 复制代码
?
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.or...
http://www.springframework.or...
http://www.springframework.or...
http://www.springframework.or...
http://www.springframework.or...
http://www.springframework.or...
http://www.springframework.or...d">
<bean id="student">
<property name="name" value="zhangsan" />
</bean>
<bean id="school">
</bean>
<bean id="factoryBeanPojo">
<property name="type" value="student" />
</bean>
</beans>
FactoryBean的实现类 :
[Java] 纯文本查看 复制代码
?
import org.springframework.beans.factory.FactoryBean;
/**
* @author 作者 wangbiao
* @date 创建时间:2016年11月14日 上午11:19:31
* @parameter
* @return
*/
public class FactoryBeanPojo implements FactoryBean{
private String type;
@Override
public Object getObject() throws Exception {
if("student".equals(type)){
return new Student();
}else{
return new School();
}
}
@Override
public Class getObjectType() {
return School.class;
}
@Override
public boolean isSingleton() {
return true;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
普通的bean:
[Java] 纯文本查看 复制代码
?
/**
* @author 作者 wangbiao
* @date 创建时间:2016年11月14日 上午11:13:18
* @parameter
* @return
*/
public class School {
private String schoolName;
private String address;
private int studentNumber;
public String getSchoolName() {
return schoolName;
}
public void setSchoolName(String schoolName) {
this.schoolName = schoolName;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public int getStudentNumber() {
return studentNumber;
}
public void setStudentNumber(int studentNumber) {
this.studentNumber = studentNumber;
}
@Override
public String toString() {
return "School [schoolName=" + schoolName + ", address=" + address
+ ", studentNumber=" + studentNumber + "]";
}
}
测试类 :
[Java] 纯文本查看 复制代码
?
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.spring.bean.FactoryBeanPojo;
/**
* @author 作者 wangbiao
* @date 创建时间:2016年11月14日 上午11:11:35
* @parameter
* @return
*/
public class FactoryBeanTest {
public static void main(String[] args){
String url = "com/spring/config/BeanConfig.xml";
ClassPathXmlApplicationContext cpxa = new ClassPathXmlApplicationContext(url);
Object school= cpxa.getBean("factoryBeanPojo");
FactoryBeanPojo factoryBeanPojo= (FactoryBeanPojo) cpxa.getBean("&factoryBeanPojo");
System.out.println(school.getClass().getName());
System.out.println(factoryBeanPojo.getClass().getName());
}
}
输出的结果:
[HTML] 纯文本查看 复制代码
?
十一月 16, 2016 10:28:24 上午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@1e8ee5c0: startup date [Wed Nov 16 10:28:24 CST 2016]; root of context hierarchy
十一月 16, 2016 10:28:24 上午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [com/spring/config/BeanConfig.xml]
十一月 16, 2016 10:28:24 上午 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@35b793ee: defining beans [student,school,factoryBeanPojo]; root of factory hierarchy
com.spring.bean.Student
com.spring.bean.FactoryBeanPojo
从结果上可以看到当从IOC容器中获取FactoryBeanPojo对象的时候,用getBean(String BeanName)获取的确是Student对象,可以看到在FactoryBeanPojo中的type属性设置为student的时候,会在getObject()方法中返回Student对象。所以说从IOC容器获取实现了FactoryBean的实现类时,返回的却是实现类中的getObject方法返回的对象,要想获取FactoryBean的实现类,得在getBean(String BeanName)中的BeanName之前加上&,写成getBean(String &BeanName)。
BeanFactory 简介以及它 和FactoryBean的区别
BeanFactory 简介以及它 和FactoryBean的区别
BeanFacotry是spring中比较原始的Factory。如XMLBeanFactory就是一种典型的BeanFactory。原始的BeanFactory无法支持spring的许多插件,如AOP功能、Web应用等。
ApplicationContext接口,它由BeanFactory接口派生而来,ApplicationContext包含BeanFactory的所有功能,通常建议比BeanFactory优先
BeanFactory和FactoryBean的区别
BeanFactory是接口,提供了OC容器最基本的形式,给具体的IOC容器的实现提供了规范,
FactoryBean也是接口,为IOC容器中Bean的实现提供了更加灵活的方式,FactoryBean在IOC容器的基础上给Bean的实现加上了一个简单工厂模式和装饰模式(如果想了解装饰模式参考:修饰者模式(装饰者模式,Decoration) 我们可以在getObject()方法中灵活配置。其实在Spring源码中有很多FactoryBean的实现类.
区别:BeanFactory是个Factory,也就是IOC容器或对象工厂,FactoryBean是个Bean。在Spring中,所有的Bean都是由BeanFactory(也就是IOC容器)来进行管理的。但对FactoryBean而言,这个Bean不是简单的Bean,而是一个能生产或者修饰对象生成的工厂Bean,它的实现与设计模式中的工厂模式和修饰器模式类似
1、 BeanFactory
BeanFactory,以Factory结尾,表示它是一个工厂类(接口), 它负责生产和管理bean的一个工厂。在Spring中,BeanFactory是IOC容器的核心接口,它的职责包括:实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。BeanFactory只是个接口,并不是IOC容器的具体实现,但是Spring容器给出了很多种实现,如 DefaultListableBeanFactory、XmlBeanFactory、ApplicationContext等,其中XmlBeanFactory就是常用的一个,该实现将以XML方式描述组成应用的对象及对象间的依赖关系。XmlBeanFactory类将持有此XML配置元数据,并用它来构建一个完全可配置的系统或应用。
都是附加了某种功能的实现。 它为其他具体的IOC容器提供了最基本的规范,例如DefaultListableBeanFactory,XmlBeanFactory,ApplicationContext 等具体的容器都是实现了BeanFactory,再在其基础之上附加了其他的功能。
BeanFactory和ApplicationContext就是spring框架的两个IOC容器,现在一般使用ApplicationnContext,其不但包含了BeanFactory的作用,同时还进行更多的扩展。
BeanFacotry是spring中比较原始的Factory。如XMLBeanFactory就是一种典型的BeanFactory。
原始的BeanFactory无法支持spring的许多插件,如AOP功能、Web应用等。ApplicationContext接口,它由BeanFactory接口派生而来,
ApplicationContext包含BeanFactory的所有功能,通常建议比BeanFactory优先
ApplicationContext以一种更向面向框架的方式工作以及对上下文进行分层和实现继承,ApplicationContext包还提供了以下的功能:
• MessageSource, 提供国际化的消息访问
• 资源访问,如URL和文件
• 事件传播
• 载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的web层;
在不使用spring框架之前,我们的service层中要使用dao层的对象,不得不在service层中new一个对象。存在的问题:层与层之间的依赖。
service层要用dao层对象需要配置到xml配置文件中,至于对象是怎么创建的,关系是怎么组合的都交给了spring框架去实现。
1 Resource resource = new FileSystemResource("beans.xml"); 2 BeanFactory factory = new XmlBeanFactory(resource);
1 ClassPathResource resource = new ClassPathResource("beans.xml"); 2 BeanFactory factory = new XmlBeanFactory(resource);
1 ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"applicationContext.xml", "applicationContext-part2.xml"}); 3 BeanFactory factory = (BeanFactory) context;
基本就是这些了,接着使用getBean(String beanName)方法就可以取得bean的实例;BeanFactory提供的方法及其简单,仅提供了六种方法供客户调用:
- boolean containsBean(String beanName) 判断工厂中是否包含给定名称的bean定义,若有则返回true
- Object getBean(String) 返回给定名称注册的bean实例。根据bean的配置情况,如果是singleton模式将返回一个共享实例,否则将返回一个新建的实例,如果没有找到指定bean,该方法可能会抛出异常
- Object getBean(String, Class) 返回以给定名称注册的bean实例,并转换为给定class类型
- Class getType(String name) 返回给定名称的bean的Class,如果没有找到指定的bean实例,则排除NoSuchBeanDefinitionException异常
- boolean isSingleton(String) 判断给定名称的bean定义是否为单例模式
- String[] getAliases(String name) 返回给定bean名称的所有别名
package org.springframework.beans.factory; import org.springframework.beans.BeansException; public interface BeanFactory { String FACTORY_BEAN_PREFIX = "&"; Object getBean(String name) throws BeansException; <T> T getBean(String name, Class<T> requiredType) throws BeansException; <T> T getBean(Class<T> requiredType) throws BeansException; Object getBean(String name, Object... args) throws BeansException; boolean containsBean(String name); boolean isSingleton(String name) throws NoSuchBeanDefinitionException; boolean isPrototype(String name) throws NoSuchBeanDefinitionException; boolean isTypeMatch(String name, Class<?> targetType) throws NoSuchBeanDefinitionException; Class<?> getType(String name) throws NoSuchBeanDefinitionException; String[] getAliases(String name); }
2、FactoryBean
一般情况下,Spring通过反射机制利用<bean>的class属性指定实现类实例化Bean,在某些情况下,实例化Bean过程比较复杂,如果按照传统的方式,则需要在<bean>中提供大量的配置信息。配置方式的灵活性是受限的,这时采用编码的方式可能会得到一个简单的方案。Spring为此提供了一个org.springframework.bean.factory.FactoryBean的工厂类接口,用户可以通过实现该接口定制实例化Bean的逻辑。FactoryBean接口对于Spring框架来说占用重要的地位,Spring自身就提供了70多个FactoryBean的实现。它们隐藏了实例化一些复杂Bean的细节,给上层应用带来了便利。从Spring3.0开始,FactoryBean开始支持泛型,即接口声明改为FactoryBean<T>的形式
以Bean结尾,表示它是一个Bean,不同于普通Bean的是:它是实现了FactoryBean<T>接口的Bean,根据该Bean的ID从BeanFactory中获取的实际上是FactoryBean的getObject()返回的对象,而不是FactoryBean本身,如果要获取FactoryBean对象,请在id前面加一个&符号来获取。
例如自己实现一个FactoryBean,功能:用来代理一个对象,对该对象的所有方法做一个拦截,在调用前后都输出一行LOG,模仿ProxyFactoryBean的功能。
/** * my factory bean<p> * 代理一个类,拦截该类的所有方法,在方法的调用前后进行日志的输出 * @author daniel.zhao * */ public class MyFactoryBean implements FactoryBean<Object>, InitializingBean, DisposableBean { private static final Logger logger = LoggerFactory.getLogger(MyFactoryBean.class); private String interfaceName; private Object target; private Object proxyObj; @Override public void destroy() throws Exception { logger.debug("destroy......"); } @Override public void afterPropertiesSet() throws Exception { proxyObj = Proxy.newProxyInstance( this.getClass().getClassLoader(), new Class[] { Class.forName(interfaceName) }, new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { logger.debug("invoke method......" + method.getName()); logger.debug("invoke method before......" + System.currentTimeMillis()); Object result = method.invoke(target, args); logger.debug("invoke method after......" + System.currentTimeMillis()); return result; } }); logger.debug("afterPropertiesSet......"); } @Override public Object getObject() throws Exception { logger.debug("getObject......"); return proxyObj; } @Override public Class<?> getObjectType() { return proxyObj == null ? Object.class : proxyObj.getClass(); } @Override public boolean isSingleton() { return true; } public String getInterfaceName() { return interfaceName; } public void setInterfaceName(String interfaceName) { this.interfaceName = interfaceName; } public Object getTarget() { return target; } public void setTarget(Object target) { this.target = target; } public Object getProxyObj() { return proxyObj; } public void setProxyObj(Object proxyObj) { this.proxyObj = proxyObj; } }
XML-Bean配置如下
1 <bean id="fbHelloWorldService"> 2 <property name="interfaceName" value="com.ebao.xxx.HelloWorldService" /> 3 <property name="target" ref="helloWorldService" /> 4 </bean>
Junit Test class
@RunWith(JUnit4ClassRunner.class) @ContextConfiguration(classes = { MyFactoryBeanConfig.class }) public class MyFactoryBeanTest { @Autowired private ApplicationContext context; /** * 测试验证FactoryBean原理,代理一个servcie在调用其方法的前后,打印日志亦可作其他处理 * 从ApplicationContext中获取自定义的FactoryBean * context.getBean(String beanName) ---> 最终获取到的Object是FactoryBean.getObejct(), * 使用Proxy.newInstance生成service的代理类 */ @Test public void testFactoryBean() { HelloWorldService helloWorldService = (HelloWorldService) context.getBean("fbHelloWorldService"); helloWorldService.getBeanName(); helloWorldService.sayHello(); } }
FactoryBean是一个接口,当在IOC容器中的Bean实现了FactoryBean后,通过getBean(String BeanName)获取到的Bean对象并不是FactoryBean的实现类对象,而是这个实现类中的getObject()方法返回的对象。要想获取FactoryBean的实现类,就要getBean(&BeanName),在BeanName之前加上&。
Java代码
package org.springframework.beans.factory; public interface FactoryBean<T> { T getObject() throws Exception; Class<?> getObjectType(); boolean isSingleton(); }
在该接口中还定义了以下3个方法:
TgetObject():返回由FactoryBean创建的Bean实例,如果isSingleton()返回true,则该实例会放到Spring容器中单实例缓存池中;
booleanisSingleton():返回由FactoryBean创建的Bean实例的作用域是singleton还是prototype;
Class<T>getObjectType():返回FactoryBean创建的Bean类型。
当配置文件中<bean>的class属性配置的实现类是FactoryBean时,通过getBean()方法返回的不是FactoryBean本身,而是FactoryBean#getObject()方法所返回的对象,相当于FactoryBean#getObject()代理了getBean()方法。
例:如果使用传统方式配置下面Car的<bean>时,Car的每个属性分别对应一个<property>元素标签。
package com.baobaotao.factorybean; public class Car { private int maxSpeed ; private String brand ; private double price ; public int getMaxSpeed () { return this . maxSpeed ; } public void setMaxSpeed ( int maxSpeed ) { this . maxSpeed = maxSpeed; } public String getBrand () { return this . brand ; } public void setBrand ( String brand ) { this . brand = brand; } public double getPrice () { return this . price ; } public void setPrice ( double price ) { this . price = price; } }
如果用FactoryBean的方式实现就灵活点,下例通过逗号分割符的方式一次性的为Car的所有属性指定配置值:
package com.baobaotao.factorybean; import org.springframework.beans.factory.FactoryBean; public class CarFactoryBean implements FactoryBean<Car> { private String carInfo ; public Car getObject () throws Exception { Car car = new Car () ; String [] infos = carInfo .split ( "," ) ; car.setBrand ( infos [ 0 ]) ; car.setMaxSpeed ( Integer. valueOf ( infos [ 1 ])) ; car.setPrice ( Double. valueOf ( infos [ 2 ])) ; return car; } public Class<Car> getObjectType () { return Car. class ; } public boolean isSingleton () { return false ; } public String getCarInfo () { return this . carInfo ; } // 接受逗号分割符设置属性信息 public void setCarInfo ( String carInfo ) { this . carInfo = carInfo; } }
有了这个CarFactoryBean后,就可以在配置文件中使用下面这种自定义的配置方式配置CarBean了:
<bean d="car"P:carInfo="法拉利,400,2000000"/>
当调用getBean("car")时,Spring通过反射机制发现CarFactoryBean实现了FactoryBean的接口,这时Spring容器就调用接口方法CarFactoryBean#getObject()方法返回。如果希望获取CarFactoryBean的实例,则需要在使用getBean(beanName)方法时在beanName前显示的加上"&"前缀:如getBean("&car");
下面是一个应用FactoryBean的例子
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"> <bean id="student" class="com.spring.bean.Student"> <property name="name" value="zhangsan" /> </bean> <bean id="school" class="com.spring.bean.School"> </bean> <bean id="factoryBeanPojo" class="com.spring.bean.FactoryBeanPojo"> <property name="type" value="student" /> </bean> </beans>
FactoryBean的实现类
import org.springframework.beans.factory.FactoryBean; /** * @author 作者 wangbiao * @date 创建时间:2016年11月14日 上午11:19:31 * @parameter * @return */ public class FactoryBeanPojo implements FactoryBean{ private String type; @Override public Object getObject() throws Exception { if("student".equals(type)){ return new Student(); }else{ return new School(); } } @Override public Class getObjectType() { return School.class; } @Override public boolean isSingleton() { return true; } public String getType() { return type; } public void setType(String type) { this.type = type; } }
普通的bean
/** * @author 作者 wangbiao * @date 创建时间:2016年11月14日 上午11:13:18 * @parameter * @return */ public class School { private String schoolName; private String address; private int studentNumber; public String getSchoolName() { return schoolName; } public void setSchoolName(String schoolName) { this.schoolName = schoolName; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public int getStudentNumber() { return studentNumber; } public void setStudentNumber(int studentNumber) { this.studentNumber = studentNumber; } @Override public String toString() { return "School [schoolName=" + schoolName + ", address=" + address + ", studentNumber=" + studentNumber + "]"; } }
测试类
import org.springframework.context.support.ClassPathXmlApplicationContext; import com.spring.bean.FactoryBeanPojo; /** * @author 作者 wangbiao * @date 创建时间:2016年11月14日 上午11:11:35 * @parameter * @return */ public class FactoryBeanTest { public static void main(String[] args){ String url = "com/spring/config/BeanConfig.xml"; ClassPathXmlApplicationContext cpxa = new ClassPathXmlApplicationContext(url); Object school= cpxa.getBean("factoryBeanPojo"); FactoryBeanPojo factoryBeanPojo= (FactoryBeanPojo) cpxa.getBean("&factoryBeanPojo"); System.out.println(school.getClass().getName()); System.out.println(factoryBeanPojo.getClass().getName()); } }
输出的结果:
十一月 16, 2016 10:28:24 上午 org.springframework.context.support.AbstractApplicationContext prepareRefresh INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@1e8ee5c0: startup date [Wed Nov 16 10:28:24 CST 2016]; root of context hierarchy 十一月 16, 2016 10:28:24 上午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions INFO: Loading XML bean definitions from class path resource [com/spring/config/BeanConfig.xml] 十一月 16, 2016 10:28:24 上午 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@35b793ee: defining beans [student,school,factoryBeanPojo]; root of factory hierarchy com.spring.bean.Student com.spring.bean.FactoryBeanPojo
从结果上可以看到当从IOC容器中获取FactoryBeanPojo对象的时候,用getBean(String BeanName)获取的确是Student对象,可以看到在FactoryBeanPojo中的type属性设置为student的时候,会在getObject()方法中返回Student对象。所以说从IOC容器获取实现了FactoryBean的实现类时,返回的却是实现类中的getObject方法返回的对象,要想获取FactoryBean的实现类,得在getBean(String BeanName)中的BeanName之前加上&,写成getBean(String &BeanName)。
BeanFactory与FactoryBean的区别
BeanFactory是个Factory,也就是IOC容器或对象工厂,FactoryBean是个Bean。在Spring中,所有的Bean都是由BeanFactory(也就是IOC容器)来进行管理的。但对FactoryBean而言,这个Bean不是简单的Bean,而是一个能生产或者修饰对象生成的工厂Bean,它的实现与设计模式中的工厂模式和修饰器模式类似
@Service public class FactoryBeanDemo implements FactoryBean { @Override public Object getObject() throws Exception { return new FactoryB(); } @Override public Class<?> getObjectType() { return FactoryB.class; } }
@Test public void test4() { FactoryB factoryB = (FactoryB)applicationContext.getBean("factoryBeanDemo"); System.out.println(factoryB); FactoryBeanDemo factoryBeanDemo = (FactoryBeanDemo)applicationContext.getBean("&factoryBeanDemo"); System.out.println(factoryBeanDemo); }
关于MongoFactoryBean和SimpleMongoDbFactory之间的区别和mongorepository和mongotemplate的介绍现已完结,谢谢您的耐心阅读,如果想了解更多关于Activiti的BeanFactory和FactoryBean的区别、BeanFactory 和FactoryBean的区别、BeanFactory 简介以及它 和FactoryBean的区别、BeanFactory与FactoryBean的区别的相关知识,请在本站寻找。
对于想了解Java XML:ClassCastException DeferredTextImpl的读者,本文将是一篇不可错过的文章,并且为您提供关于applicationContext-common.xml]; nested exception is java.lang.NoClassDefFoundError: org/w3c/dom/E...、Caused by: java.lang.ClassCastException、Caused by: java.lang.ClassNotFoundException: org.apache.jasper.runtime.JspApplicationContextImpl、ClassCastException:无法转换为com.sun.xml.internal.bind.v2.runtime.reflect.Accessor的有价值信息。
本文目录一览:- Java XML:ClassCastException DeferredTextImpl
- applicationContext-common.xml]; nested exception is java.lang.NoClassDefFoundError: org/w3c/dom/E...
- Caused by: java.lang.ClassCastException
- Caused by: java.lang.ClassNotFoundException: org.apache.jasper.runtime.JspApplicationContextImpl
- ClassCastException:无法转换为com.sun.xml.internal.bind.v2.runtime.reflect.Accessor
Java XML:ClassCastException DeferredTextImpl
这是我的代码:
// get the factoryDocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();try { // Using factory get an instance of document builderDocumentBuilder db = dbf.newDocumentBuilder();// parse using builder to get DOM representation of the XML file dom = db.parse(file);} catch (ParserConfigurationException pce) { pce.printStackTrace();} catch (SAXException se) { se.printStackTrace();} catch (IOException ioe) { ioe.printStackTrace();}NodeList n1 = dom.getChildNodes();Element e1 = (Element) n1.item(0);System.out.println(n1.getLength());System.out.println(e1.getNodeName());NodeList n2 = n1.item(0).getChildNodes();Element e2 = (Element) n2.item(0); //Line 61System.out.println(n2.getLength());System.out.println(e2.getNodeName());
这是我的XML文件:
<?xml version="1.0" encoding="utf-8"?><test-fw:testxmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:test-fw="http://simitar/test-fw"><rule-tree><rule><property name="contiguous"> true</property><property name="inOrder">false</property><property name="exact">false</property><property name="lines">modelInstantiated</property></rule><rule><property name="contiguous"> true</property><property name="inOrder">true</property><property name="exact">false</property><property name="lines">InitEvent</property></rule></rule-tree></test-fw:test>
这是我的输出:
1test-fw:testException in thread "main" java.lang.ClassCastException: com.sun.org.apache.xerces.internal.dom.DeferredTextImpl cannot be cast to org.w3c.dom.Element at testpack.Main.run(Main.java:61) at testpack.Main.main(Main.java:86)
我不断收到此错误。我完全迷路了。我不知道该怎么做。我希望能够有一个节点,并且能够抓住它的所有子节点并将它们放入数组或列表中,以便我可以遍历它们。
这是我所有的进口商品:
import java.io.File;import java.io.IOException;import java.util.List;import java.util.Stack;import javax.xml.parsers.DocumentBuilder;import javax.xml.parsers.DocumentBuilderFactory;import javax.xml.parsers.ParserConfigurationException;import org.w3c.dom.Document;import org.w3c.dom.Element;import org.w3c.dom.NodeList;import org.xml.sax.SAXException;
我经历了最艰难的尝试来获取此Java来解析此XML文件。
答案1
小编典典NodeList n1 = dom.getChildNodes();Element e1 = (Element) n1.item(0);
该节点不是Element
,而是Node
。
试试这个:
Node no1 = (Node) n1.item(0);
例如,节点可以是文本节点或元素。特别是,
<root><element/></root>
是 4个 节点。一个root
元素 ,一个包含的 文本节点\n
,该element
元素 和另一个包含的
文本节点\n
。
applicationContext-common.xml]; nested exception is java.lang.NoClassDefFoundError: org/w3c/dom/E...
14:59:16,747 ERROR ContextLoader:350 - Context initialization failed
org.springframework.beans.factory.BeanDefinitionStoreException: Unexpected exception parsing XML document from file [D:\eclipse\workspace_web\.metadata\.plugins\org.eclipse.wst.server.core\tmp4\wtpwebapps\czyxyg_ws\WEB-INF\classes\applicationContext-common.xml]; nested exception is java.lang.NoClassDefFoundError: org/w3c/dom/ElementTraversal
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:414)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:336)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:304)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:181)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:217)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:188)
at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:125)
at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:94)
at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:129)
at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:614)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:515)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:443)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:325)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:107)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4973)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5467)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NoClassDefFoundError: org/w3c/dom/ElementTraversal
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at org.apache.catalina.loader.WebappClassLoader.findClassInternal(WebappClassLoader.java:2944)
at org.apache.catalina.loader.WebappClassLoader.findClass(WebappClassLoader.java:1208)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1688)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1569)
at org.apache.xerces.parsers.AbstractDOMParser.startDocument(Unknown Source)
at org.apache.xerces.impl.xs.XMLSchemaValidator.startDocument(Unknown Source)
at org.apache.xerces.impl.dtd.XMLDTDValidator.startDocument(Unknown Source)
at org.apache.xerces.impl.XMLDocumentScannerImpl.startEntity(Unknown Source)
at org.apache.xerces.impl.XMLVersionDetector.startDocumentParsing(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
at org.apache.xerces.parsers.DOMParser.parse(Unknown Source)
at org.apache.xerces.jaxp.DocumentBuilderImpl.parse(Unknown Source)
at org.springframework.beans.factory.xml.DefaultDocumentLoader.loadDocument(DefaultDocumentLoader.java:76)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadDocument(XmlBeanDefinitionReader.java:429)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:391)
... 22 more
Caused by: java.lang.ClassNotFoundException: org.w3c.dom.ElementTraversal
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1718)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1569)
... 42 more
pom文件引入:
-
<dependency>
<groupId>xml-apis</groupId>
<artifactId>xml-apis</artifactId>
<version>1.4.01</version>
</dependency>
Caused by: java.lang.ClassCastException
报错信息如下: java.lang.reflect.InvocationTargetException at sun.reflect.NativeMethodAccessorImpl.invoke0 (Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke (Method.java:498) at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs (LauncherImpl.java:389) at com.sun.javafx.application.LauncherImpl.launchApplication (LauncherImpl.java:328) at sun.reflect.NativeMethodAccessorImpl.invoke0 (Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke (Method.java:498) at sun.launcher.LauncherHelper$FXHelper.main (LauncherHelper.java:767) Caused by: java.lang.RuntimeException: Exception in Application start method at com.sun.javafx.application.LauncherImpl.launchApplication1 (LauncherImpl.java:917) at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$155 (LauncherImpl.java:182) at java.lang.Thread.run (Thread.java:745) Caused by: java.lang.ClassCastException: java.lang.String cannot be cast to javafx.beans.value.ObservableValue at ruiyi.gui.controller.special.AbstractSpecificAnalysisView.lambda$bindDataToJFXTreeTableColumnDT$1 (AbstractSpecificAnalysisView.java:106) at javafx.scene.control.TreeTableColumn.getCellObservableValue (TreeTableColumn.java:563) at javafx.scene.control.TreeTableColumn.getCellObservableValue (TreeTableColumn.java:548) at javafx.scene.control.TreeTableCell.updateItem (TreeTableCell.java:635) at javafx.scene.control.TreeTableCell.indexChanged (TreeTableCell.java:457) at javafx.scene.control.IndexedCell.updateIndex (IndexedCell.java:116) at com.sun.javafx.scene.control.skin.TableRowSkinBase.updateCells (TableRowSkinBase.java:533) at com.sun.javafx.scene.control.skin.TreeTableRowSkin.updateCells (TreeTableRowSkin.java:220) at com.sun.javafx.scene.control.skin.TableRowSkinBase.init (TableRowSkinBase.java:147) at com.sun.javafx.scene.control.skin.TreeTableRowSkin.(TreeTableRowSkin.java:89) at com.jfoenix.skins.JFXTreeTableRowSkin.(JFXTreeTableRowSkin.java:59) at com.jfoenix.controls.JFXTreeTableRow.createDefaultSkin (JFXTreeTableRow.java:45) at javafx.scene.control.Control.impl_processCSS (Control.java:872) at javafx.scene.Node.processCSS (Node.java:9056) at javafx.scene.Node.applyCss (Node.java:9153) at com.sun.javafx.scene.control.skin.VirtualFlow.setCellIndex (VirtualFlow.java:1964) at com.sun.javafx.scene.control.skin.VirtualFlow.getCell (VirtualFlow.java:1797) at com.sun.javafx.scene.control.skin.VirtualFlow.getCellLength (VirtualFlow.java:1879) at com.sun.javafx.scene.control.skin.VirtualFlow.computeViewportOffset (VirtualFlow.java:2528) at com.sun.javafx.scene.control.skin.VirtualFlow.layoutChildren (VirtualFlow.java:1189) at javafx.scene.Parent.layout (Parent.java:1087) at javafx.scene.Parent.layout (Parent.java:1093) at javafx.scene.Parent.layout (Parent.java:1093) at javafx.scene.Parent.layout (Parent.java:1093) at javafx.scene.Parent.layout (Parent.java:1093) at javafx.scene.Parent.layout (Parent.java:1093) at javafx.scene.Parent.layout (Parent.java:1093) at javafx.scene.Parent.layout (Parent.java:1093) at javafx.scene.Parent.layout (Parent.java:1093) at javafx.scene.Parent.layout (Parent.java:1093) at javafx.scene.Parent.layout (Parent.java:1093) at javafx.scene.Parent.layout (Parent.java:1093) at javafx.scene.Parent.layout (Parent.java:1093) at javafx.scene.Parent.layout (Parent.java:1093) at javafx.scene.Parent.layout (Parent.java:1093) at javafx.scene.Parent.layout (Parent.java:1093) at javafx.scene.Parent.layout (Parent.java:1093) at javafx.scene.Parent.layout (Parent.java:1093) at javafx.scene.Parent.layout (Parent.java:1093) at javafx.scene.Parent.layout (Parent.java:1093) at javafx.scene.Scene.doLayoutPass (Scene.java:552) at javafx.scene.Scene.preferredSize (Scene.java:1646) at javafx.scene.Scene.impl_preferredSize (Scene.java:1720) at javafx.stage.Window$9.invalidated (Window.java:846) at javafx.beans.property.BooleanPropertyBase.markInvalid (BooleanPropertyBase.java:109) at javafx.beans.property.BooleanPropertyBase.set (BooleanPropertyBase.java:144) at javafx.stage.Window.setShowing (Window.java:922) at javafx.stage.Window.show (Window.java:937) at javafx.stage.Stage.show (Stage.java:259) at application.Main.start (Main.java:80) at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$162 (LauncherImpl.java:863) at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$175 (PlatformImpl.java:326) at com.sun.javafx.application.PlatformImpl.lambda$null$173 (PlatformImpl.java:295) at java.security.AccessController.doPrivileged (Native Method) at com.sun.javafx.application.PlatformImpl.lambda$runLater$174 (PlatformImpl.java:294) at com.sun.glass.ui.InvokeLaterDispatcher$Future.run (InvokeLaterDispatcher.java:95) at com.sun.glass.ui.win.WinApplication._runLoop (Native Method) at com.sun.glass.ui.win.WinApplication.lambda$null$148 (WinApplication.java:191) 这里的 ObservableValue 是 javafx.beans.value 包下的 interface 我的代码是这样的: protected void bindDataToJFXTreeTableColumnDT (JFXTreeTableColumn column, String key) { // 数据查找绑定到 table view column.setCellValueFactory ((TreeTableColumn.CellDataFeatures param) -> { if (column.validateValue (param)) return param.getValue ().getValue ().getValue (key); else return column.getComputedValue (param); }); } 我同事写的代码是这样的 protected void bindDataToJFXTreeTableColumn (JFXTreeTableColumn column, String key) { // 数据查找绑定到 table view column.setCellValueFactory ((TreeTableColumn.CellDataFeatures param) -> { if (column.validateValue (param)) return param.getValue ().getValue ().getValue (key); else return column.getComputedValue (param); }); } 同事的代码执行不报错,我的报错。Caused by: java.lang.ClassNotFoundException: org.apache.jasper.runtime.JspApplicationContextImpl
Exception in thread "Thread-1" java.lang.NoClassDefFoundError: org/apache/jasper/runtime/JspApplicationContextImpl
at org.apache.jasper.servlet.JspServlet.destroy(JspServlet.java:412)
at org.eclipse.jetty.servlet.ServletHolder.destroyInstance(ServletHolder.java:362)
at org.eclipse.jetty.servlet.ServletHolder.doStop(ServletHolder.java:336)
at org.eclipse.jetty.util.component.AbstractLifeCycle.stop(AbstractLifeCycle.java:84)
at org.eclipse.jetty.servlet.ServletHandler.doStop(ServletHandler.java:208)
at org.eclipse.jetty.util.component.AbstractLifeCycle.stop(AbstractLifeCycle.java:84)
at org.eclipse.jetty.server.handler.HandlerWrapper.doStop(HandlerWrapper.java:102)
at org.eclipse.jetty.security.SecurityHandler.doStop(SecurityHandler.java:356)
at org.eclipse.jetty.security.ConstraintSecurityHandler.doStop(ConstraintSecurityHandler.java:237)
at org.eclipse.jetty.util.component.AbstractLifeCycle.stop(AbstractLifeCycle.java:84)
at org.eclipse.jetty.server.handler.HandlerWrapper.doStop(HandlerWrapper.java:102)
at org.eclipse.jetty.server.session.SessionHandler.doStop(SessionHandler.java:133)
at org.eclipse.jetty.util.component.AbstractLifeCycle.stop(AbstractLifeCycle.java:84)
at org.eclipse.jetty.server.handler.HandlerWrapper.doStop(HandlerWrapper.java:102)
at org.eclipse.jetty.server.handler.ContextHandler.doStop(ContextHandler.java:798)
at org.eclipse.jetty.servlet.ServletContextHandler.doStop(ServletContextHandler.java:153)
at org.eclipse.jetty.webapp.WebAppContext.doStop(WebAppContext.java:491)
at org.mortbay.jetty.plugin.JettyWebAppContext.doStop(JettyWebAppContext.java:264)
at org.eclipse.jetty.util.component.AbstractLifeCycle.stop(AbstractLifeCycle.java:84)
at org.eclipse.jetty.server.handler.HandlerCollection.doStop(HandlerCollection.java:245)
at org.eclipse.jetty.util.component.AbstractLifeCycle.stop(AbstractLifeCycle.java:84)
at org.eclipse.jetty.server.handler.HandlerCollection.doStop(HandlerCollection.java:245)
at org.eclipse.jetty.util.component.AbstractLifeCycle.stop(AbstractLifeCycle.java:84)
at org.eclipse.jetty.server.handler.HandlerWrapper.doStop(HandlerWrapper.java:102)
at org.eclipse.jetty.server.Server.doStop(Server.java:323)
at org.eclipse.jetty.util.component.AbstractLifeCycle.stop(AbstractLifeCycle.java:84)
at org.eclipse.jetty.util.thread.ShutdownThread.run(ShutdownThread.java:124)
Caused by: java.lang.ClassNotFoundException: org.apache.jasper.runtime.JspApplicationContextImpl
at org.codehaus.plexus.classworlds.strategy.SelfFirstStrategy.loadClass(SelfFirstStrategy.java:50)
at org.codehaus.plexus.classworlds.realm.ClassRealm.unsynchronizedLoadClass(ClassRealm.java:271)
at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:247)
at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:239)
... 27 more
ClassCastException:无法转换为com.sun.xml.internal.bind.v2.runtime.reflect.Accessor
我有一个SOAP Web服务,正在尝试在应用程序内部调用。我正在使用cxf-codegen-plugin(3.1.10)从WSDL生成源。
使用生成的客户端,如果我在应用程序内调用Web服务,则效果很好。但是,我还针对导致问题的应用程序中的同一软件包使用了另一个JAXB实例。
例如,以下代码很好用:
OutboundServicePortType service = new OutboundService().getOutboundServicePort();
service.sendMessage(message);
但是,在此之前初始化一个新的JAXB实例会导致getOutboundServicePort()
调用失败:
JAXBContext.newInstance(SendMessageRequest.class);
OutboundServicePortType service = new OutboundService().getOutboundServicePort();
service.sendMessage(message);
使用以下堆栈跟踪:
Caused by: java.lang.ClassCastException: outbound.model.standard.StandardOutboundMessage$JaxbAccessorF_messageUUId cannot be cast to com.sun.xml.internal.bind.v2.runtime.reflect.Accessor
at com.sun.xml.internal.bind.v2.runtime.reflect.opt.OptimizedAccessorFactory.instanciate(OptimizedAccessorFactory.java:190)
at com.sun.xml.internal.bind.v2.runtime.reflect.opt.OptimizedAccessorFactory.get(OptimizedAccessorFactory.java:179)
at com.sun.xml.internal.bind.v2.runtime.reflect.Accessor$FieldReflection.optimize(Accessor.java:271)
at com.sun.xml.internal.bind.v2.runtime.property.SingleElementLeafProperty.<init>(SingleElementLeafProperty.java:77)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
at com.sun.xml.internal.bind.v2.runtime.property.PropertyFactory.create(PropertyFactory.java:113)
at com.sun.xml.internal.bind.v2.runtime.ClassBeanInfoImpl.<init>(ClassBeanInfoImpl.java:166)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getOrCreate(JAXBContextImpl.java:488)
at com.sun.xml.internal.bind.v2.runtime.ClassBeanInfoImpl.<init>(ClassBeanInfoImpl.java:153)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getOrCreate(JAXBContextImpl.java:488)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:305)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:124)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1123)
at com.sun.xml.internal.bind.v2.ContextFactory.createContext(ContextFactory.java:147)
at com.sun.xml.internal.bind.api.JAXBRIContext.newInstance(JAXBRIContext.java:152)
at com.sun.xml.internal.bind.api.JAXBRIContext.newInstance(JAXBRIContext.java:96)
at com.sun.xml.internal.ws.developer.JAXBContextFactory$1.createJAXBContext(JAXBContextFactory.java:98)
at com.sun.xml.internal.ws.db.glassfish.JAXBRIContextFactory.newContext(JAXBRIContextFactory.java:79)
... 25 more
- 我试着接受的解决方案
System.setProperty( "com.sun.xml.bind.v2.bytecode.ClassTailor.noOptimize","true");
,其 做 的工作。但是,不幸的是,在我的环境中,设置此属性不是我的选择。另外,似乎这是一个骇客,无法解决真正的问题(除非我误解了)。
我要用剩下的小绳子把自己吊死。我在这里想念什么?
关于Java XML:ClassCastException DeferredTextImpl的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于applicationContext-common.xml]; nested exception is java.lang.NoClassDefFoundError: org/w3c/dom/E...、Caused by: java.lang.ClassCastException、Caused by: java.lang.ClassNotFoundException: org.apache.jasper.runtime.JspApplicationContextImpl、ClassCastException:无法转换为com.sun.xml.internal.bind.v2.runtime.reflect.Accessor等相关知识的信息别忘了在本站进行查找喔。
在本文中,我们将详细介绍如何使用Jackson验证重复属性?的各个方面,并为您提供关于jackson常用方法的相关解答,同时,我们也将为您带来关于Java 8 Jackson验证、java – 如何使用Jackson注释序列化此JSON?、java – 有没有一种简单的方法来使用Jackson展平JSON对象属性?、Java 如何使用Jackson来反序列化对象数组的有用知识。
本文目录一览:- 如何使用Jackson验证重复属性?(jackson常用方法)
- Java 8 Jackson验证
- java – 如何使用Jackson注释序列化此JSON?
- java – 有没有一种简单的方法来使用Jackson展平JSON对象属性?
- Java 如何使用Jackson来反序列化对象数组
如何使用Jackson验证重复属性?(jackson常用方法)
我正在使用Jackson JSON库将一些JSON对象转换为POJO类。问题是,当我使用具有重复属性的JSON对象时,例如:
{ "name":"xiaopang", "email":"xiaopang1@123.com", "email":"xiaopang2@123.com"}
杰克逊报告最后一封电子邮件对"email":"xiaopang2@123.com"
,然后解析该对象。
我从JSON语法中获悉了对象中的重复键吗?反序列化具有重复属性的JSON对象时发生的情况取决于库的实现,是抛出错误还是将最后一个用于重复键。
尽管跟踪所有属性会产生开销,但是在这种情况下,是否有任何方法可以告诉Jackson报错或异常,例如“ Duplicate key”?
答案1
小编典典用 JsonParser.Feature.STRICT_DUPLICATE_DETECTION
ObjectMapper mapper = new ObjectMapper();mapper.enable(JsonParser.Feature.STRICT_DUPLICATE_DETECTION);MyPOJO result = mapper.readValue(json, MyPOJO.class);
结果是:
Exception in thread "main" com.fasterxml.jackson.core.JsonParseException: Duplicate field ''email''
您也可以尝试使用DeserializationFeature.FAIL_ON_READING_DUP_TREE_KEY
(更多信息)如果先将json字符串/输入反序列化为jackson
json树,然后反序列化为POJO,则会触发该问题。可以将其与自定义结合起来,JsonDeserializer
如下所示:
private static class MyPojoDeserializer extends JsonDeserializer<MyPOJO>{ @Override public MyPOJO deserialize(JsonParser p, DeserializationContext ctxt) throws IOException{ JsonNode tree = p.readValueAsTree(); return p.getCodec().treeToValue(tree, MyPOJO.class); }}
设置一次,并使用与以前相同的方式:
// setup ObjectMapper ObjectMapper mapper = new ObjectMapper();mapper.enable(DeserializationFeature.FAIL_ON_READING_DUP_TREE_KEY);SimpleModule module = new SimpleModule();module.addDeserializer(MyPOJO.class,new MyPojoDeserializer() );mapper.registerModule(module);// usemapper.readValue(json, MyPOJO.class);
结果:
Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: Duplicate field ''email'' for ObjectNode: not allowed when FAIL_ON_READING_DUP_TREE_KEY enabled
其他选择是自己在自定义反序列化器中或在POJO setter方法中实现所有逻辑。
Java 8 Jackson验证
我有一个springboot休息服务。用户传入一个json对象,该对象反序列化到此java pojo中:
public final class Request { private String id; private double code; private String name; public String getId() { return id; } public double getCode() { return code; } public String getName() { return name; }}
因此,用户需要传递以下json:
{ "id": “123457896”, "code": "Foo", "name": "test"}
我想将所有这些字段都设为必填项。提供更少或更多的东西将引发异常。反序列化时,有没有办法告诉杰克逊验证输入?我已经尝试过了,@JsonProperty(required=true)
但这是行不通的。显然,从这里到这里似乎JsonProperty
都没有遵守注释。
我在控制器中调用了这个验证器:
@Componentpublic class RequestValidator implements Validator { @Override public boolean supports(Class<?> clazz) { return false; } @Override public void validate(Object target, Errors errors) { String id = ((Request) target).getId(); if(id == null || id.isEmpty()) { throw new InvalidRequestException("A valid id is missing. Please provide a non-empty or non-null id."); } }}
但这在每个领域都显得乏味且丑陋。因此,鉴于我正在使用Java 8,Spring
Boot和最新版本的Jackson,在验证传入的json输入方面的最佳实践是什么?还是我已经以最新的方式进行了?
答案1
小编典典您使用了Spring Validator方法。还有另一种方法:
J2EE JSR-303 / JSR-349 Bean验证API。它提供验证注释(javax,而不是jackson)。
在这里看到两个很好的例子
java – 如何使用Jackson注释序列化此JSON?
{ fields : { "foo" : "foovalue","bar" : "barvalue" } }
我写了一个pojo如下:
public class MyPojo { @JsonProperty("fields") private List<Field> fields; static class Field { @JsonProperty("foo") private String foo; @JsonProperty("bar") private String bar; //Getters and setters for those 2 }
这显然会失败,因为我的json字段“fields”是一个hashmap,而不是一个列表.
我的问题是:是否有任何“魔术”注释可以使杰克逊将地图键识别为pojo属性名称,并将地图值分配给pojo属性值?
P.S.:我真的不想把我的领域对象当作……
private Map<String,String> fields;
…因为在我的真实世界json中,我在地图值中有复杂的对象,而不仅仅是字符串……
谢谢
总结
以上是小编为你收集整理的java – 如何使用Jackson注释序列化此JSON?全部内容。
如果觉得小编网站内容还不错,欢迎将小编网站推荐给好友。
java – 有没有一种简单的方法来使用Jackson展平JSON对象属性?
鉴于:
{ "key": { "field1": 1,"field2": 2 },"prop": "value" }
我希望将其序列化为:
{ "field1": 1,"field2": 2,"prop": "value" }
我真的不想实现JsonSerializableWithType,因为它现在很好,它只是关键类我希望字段变平.
解决方法
@JsonProperty("field1") private int getField1() @JsonProperty("field2") private int getField2()
您可能还想实现setField1()和setField2().
Java 如何使用Jackson来反序列化对象数组
支持deserialising“所有支持类型的数组”,但我不能找出确切的语法这一点。
对于单个对象,我可以这样做:
//json input{ "id" : "junk", "stuff" : "things"}//JavaMyClass instance = objectMapper.readValue(json, MyClass.class);
现在,对于数组,我想这样做:
//json input[{ "id" : "junk", "stuff" : "things"},{ "id" : "spam", "stuff" : "eggs"}]//JavaList<MyClass> entries = ?
有人知道是否有不可思议的命令吗?如果没有,那么解决方案是什么?
答案1
小编典典首先创建一个映射器:
import com.fasterxml.jackson.databind.ObjectMapper;// in play 2.3ObjectMapper mapper = new ObjectMapper();
作为数组:
MyClass[] myObjects = mapper.readValue(json, MyClass[].class);
作为列表:
List<MyClass> myObjects = mapper.readValue(jsonInput, new TypeReference<List<MyClass>>(){});
指定列表类型的另一种方法:
List<MyClass> myObjects = mapper.readValue(jsonInput, mapper.getTypeFactory().constructCollectionType(List.class, MyClass.class));
关于如何使用Jackson验证重复属性?和jackson常用方法的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于Java 8 Jackson验证、java – 如何使用Jackson注释序列化此JSON?、java – 有没有一种简单的方法来使用Jackson展平JSON对象属性?、Java 如何使用Jackson来反序列化对象数组等相关知识的信息别忘了在本站进行查找喔。
如果您想了解“Fire and forget” python async/await的知识,那么本篇文章将是您的不二之选。同时我们将深入剖析.net – 使用Task.Wait()代码包装Async / Await IAsyncOperations有什么风险?、asp.net – Async / Await和AsyncController?、Async,Await和ConfigureAwait的关系、async-await – async / await防止Angular2在模板语句中使用时呈现组件的各个方面,并给出实际的案例分析,希望能帮助到您!
本文目录一览:- “Fire and forget” python async/await
- .net – 使用Task.Wait()代码包装Async / Await IAsyncOperations有什么风险?
- asp.net – Async / Await和AsyncController?
- Async,Await和ConfigureAwait的关系
- async-await – async / await防止Angular2在模板语句中使用时呈现组件
“Fire and forget” python async/await
有时需要进行一些非关键的异步操作,但我不想等待它完成。在Tornado的协程实现中,你可以通过简单地省略yield
关键字来“触发并忘记”一个异步函数。
我一直在试图找出如何“火和忘记”与新的async/ await
在Python 3.5发布的语法。例如,一个简化的代码片段:
async def async_foo(): print("Do some stuff asynchronously here...")def bar(): async_foo() # fire and forget "async_foo()"bar()
但是,发生的事情是bar()永远不会执行,而是收到运行时警告:
RuntimeWarning: coroutine ''async_foo'' was never awaited async_foo() # fire and forget "async_foo()"
答案1
小编典典如果你使用的是Python> = 3.7
,请在任何地方替换asyncio.ensure_future
为asyncio.create_task
最新的,更好的派生task的方法。
asyncio.Task到“激发并忘记”
根据python docs
的asyncio.Task
说法,有可能启动一些协程以“在后台”执行。asyncio.ensure_future
函数创建的任务不会阻止执行(因此函数将立即返回!)。这似乎是你要求的一种“解雇”的方法。
import asyncioasync def async_foo(): print("async_foo started") await asyncio.sleep(1) print("async_foo done")async def main(): asyncio.ensure_future(async_foo()) # fire and forget async_foo() # btw, you can also create tasks inside non-async funcs print(''Do some actions 1'') await asyncio.sleep(1) print(''Do some actions 2'') await asyncio.sleep(1) print(''Do some actions 3'')if __name__ == ''__main__'': loop = asyncio.get_event_loop() loop.run_until_complete(main())
输出:
Do some actions 1async_foo startedDo some actions 2async_foo doneDo some actions 3
如果事件循环完成后正在执行任务怎么办?
请注意,asyncio
期望任务在事件循环完成时完成。因此,如果你更改main()
为:
async def main(): asyncio.ensure_future(async_foo()) # fire and forget print(''Do some actions 1'') await asyncio.sleep(0.1) print(''Do some actions 2'')程序完成后,你会收到以下警告:Task was destroyed but it is pending!task: <Task pending coro=<async_foo() running at [...]
为防止这种情况,你可以在事件循环完成后等待所有待处理的任务:
async def main(): asyncio.ensure_future(async_foo()) # fire and forget print(''Do some actions 1'') await asyncio.sleep(0.1) print(''Do some actions 2'')if __name__ == ''__main__'': loop = asyncio.get_event_loop() loop.run_until_complete(main()) # Let''s also finish all running tasks: pending = asyncio.Task.all_tasks() loop.run_until_complete(asyncio.gather(*pending))
杀死任务而不是等待任务
有时你不想等待任务完成(例如,某些任务可能创建为永久运行)。在这种情况下,你可以只取消()而不是等待它们:
import asynciofrom contextlib import suppressasync def echo_forever(): while True: print("echo") await asyncio.sleep(1)async def main(): asyncio.ensure_future(echo_forever()) # fire and forget print(''Do some actions 1'') await asyncio.sleep(1) print(''Do some actions 2'') await asyncio.sleep(1) print(''Do some actions 3'')if __name__ == ''__main__'': loop = asyncio.get_event_loop() loop.run_until_complete(main()) # Let''s also cancel all running tasks: pending = asyncio.Task.all_tasks() for task in pending: task.cancel() # Now we should await task to execute it''s cancellation. # Cancelled task raises asyncio.CancelledError that we can suppress: with suppress(asyncio.CancelledError): loop.run_until_complete(task)
输出:
Do some actions 1echoDo some actions 2echoDo some actions 3echo
.net – 使用Task.Wait()代码包装Async / Await IAsyncOperations有什么风险?
作为其中的一部分,我遇到了现有代码的问题,希望某些操作是同步的 – 例如用于文件I / O.
为了使这个现有代码适应WinRT中的IAsyncoperation样式API,我使用了一种使用扩展方法包装IAsyncoperation的技术,如:
namespace CirrIoUs.MvvmCross.Plugins.File.WinRT { public static class WinRTExtensionMethods { public static TResult Await<TResult>(this IAsyncoperation<TResult> operation) { var task = operation.AsTask(); task.Wait(); if (task.Exception != null) { // Todo - is this correct? throw task.Exception.InnerException; } return task.Result; } } }
从MvvmCross WinRT ExtensionMethods开始 – 使用与IAsyncAction类似的方法
这些包装器似乎有效 – 它们允许我在同步代码中使用Async方法,如:
public IEnumerable<string> GetFilesIn(string folderPath) { var folder = StorageFolder.GetFolderFromPathAsync(ToFullPath(folderPath)).Await(); var files = folder.GetFilesAsync().Await(); return files.Select(x => x.Name); }
我知道这并不是真正符合WinRT的精神;但我希望这些方法通常只能在后台线程上调用;我写这篇文章的目的是让我的代码跨平台兼容 – 包括那些尚未支持await-async的平台和/或尚未准备好跳转的开发人员.
所以……问题是:使用这种类型的代码我运行的风险是什么?
作为第二个问题,有没有更好的方法可以实现文件I / O等领域的代码重用?
解决方法
public static TResult Await<TResult>(this IAsyncoperation<TResult> operation) { return operation.AsTask().Result; }
如果任务尚未完成,则调用结果将同步等待.如果失败,它将抛出AgreggateException.我认为像你一样抛出InnerException是个坏主意,因为它会覆盖异常的堆栈跟踪.
关于你的实际问题,我认为使用Wait()和异步代码的最大危险是死锁.如果你在UI线程上启动一些内部使用await的操作,然后在同一个线程上使用Wait()等待它,你将遇到死锁.
如果你没有在UI线程上等待,那么这并不重要,但如果可能的话,你仍然应该避免它,因为它违背了整个异步的想法.
asp.net – Async / Await和AsyncController?
解决方法
Provided for backward compatibility with ASP.NET MVC 3.
这个类本身是空的.
换句话说,你不需要它.
Async,Await和ConfigureAwait的关系
【转自】https://mp.weixin.qq.com/s/h10V-FshGoaQUWFPfy-azg
在.NET Framework 4.5中,async / await关键字已添加到该版本中,简化多线程操作,以使异步编程更易于使用。为了最大化利用资源而不挂起UI,你应该尽可能地尝试使用异步编程。虽然async / await让异步编程更简单,但是有一些你可能不知道的细节和注意的地方
新关键字
微软在.NET框架中添加了async和await关键字。但是,使用它们,方法的返回类型应为Task类型。(我们将在稍后讨论例外情况)为了使用await关键字,您必须在方法定义中使用async。如果你在方法定义中放入async,你应该在主体方法的某个地方至少有一处await关键字,如果你缺少他,你通常会收到Visual Studio的一个警告。
以下是代码中的示例:
1 public async Task ExecuteAsync(UpdateCarCommand request, CancellationToken token = default)
2 {
3 using (var context = _contextFactory.Create())
4 {
5 var entity = context.Cars.FirstOrDefault(a => a.Id == request.Id);
6 // Mapping logic
7 await context.SaveChangesAsync(token);
8 }
9 }
如果要从异步方法返回某些内容,可以使用Task的泛型。像以下这样(如果你想返回受影响的行数)
1 public async Task<int> ExecuteAsync(UpdateCarCommand request, CancellationToken token = default)
2 {
3 using (var context = _contextFactory.Create())
4 {
5 var entity = context.Cars.FirstOrDefault(a => a.Id == request.Id);
6 // Mapping logic
7 return await context.SaveChangesAsync(token);
8 }
9 }
async.await给我们带来了什么?
虽然使用这个看起来很简单,但是它有什么帮助呢?最后,所有这些操作都是在等待数据库返回结果时(在本例中)让其他请求使用当前线程。当您向数据库、磁盘、internet等外部源发出可能需要一段时间才能运行的请求时,我们可以使用async/ wait让其他请求使用这个线程。这样,我们就不会有空闲的“worker”(线程)在那里等待完成其他任务。这就像去快餐店一样,在你点完菜之后,其他人不会点任何东西,直到你吃完为止。使用async/ await,其他人可以在你点完菜之后下他们的订单,并且可以同时处理多个订单。
它不能做什么?
这里需要注意的一件事是async/await并不是并行/多核编程。当您使用async/await时,只处理该线程,并让其他线程使用它。代码的作用类似于“同步”,因为您可以在await之后以本方法继续执行代码。因此,如果在一个方法中有四个await,则必须等到每个方法都完成后才能调用下一个方法。因此,您必须使用任务库或任何您喜欢的方法生成新线程,以使它们并行运行。但是,您也可以让每个线程使用async/wait,这样它们就不会阻塞资源了!
ConfigureAwait(false)能做什么呢?
默认情况下,当您使用async/await时,它将在开始请求的原始线程上继续运行(状态机)。但是,如果当前另一个长时间运行的进程已经接管了该线程,那么你就不得不等待它完成。要避免这个问题,可以使用ConfigureAwait的方法和false参数。当你用这个方法的时候,这将告诉Task它可以在任何可用的线程上恢复自己继续运行,而不是等待最初创建它的线程。这将加快响应速度并避免许多死锁。
但是,这里有一点点损失。当您在另一个线程上继续时,线程同步上下文将丢失,因为状态机改变。这里最大的损失是你会失去归属于线程的Culture和Language,其中包含了国家语言时区信息,以及来自原始线程的HttpContext.Current之类的信息,因此,如果您不需要以此来做多语系或操作任何HttpContext类型设置,则可以安全地进行此方法的调用。注意:如果需要language/culture,可以始终在await之前存储当前相关状态值,然后在await新线程之后重新应用它。
以下是ConfigureAwait(false)的示例:
1 public async Task<int> ExecuteAsync(UpdateCarCommand request, CancellationToken token = default)
2 {
3 using (var context = _contextFactory.Create())
4 {
5 var entity = context.Cars.FirstOrDefault(a => a.Id == request.Id);
6 // Mapping logic
7 return await context.SaveChangesAsync(token).CongifureAwait(false);
8 }
9 }
注意事项
同步 -->异步
如果要使用async/await,需要注意一些事情。您可能遇到的最大问题是处理异步方法请求同步方法。如果你开发一个新项目,通常可以将async/await从上到下贯穿于整个方法链中,而不需要做太多工作。但是,如果你在外层是同步的,并且必须调用异步库,那么就会出现一些有隐患的操作。如果一不小心,便会引发大批量的死锁
如果有同步方法调用异步方法,则必须使用ConfigureAwait(false)。如果不这样做,就会立即掉进死锁陷阱。发生的情况是主线程将调用async方法,最终会阻塞这个线程,直到那个async方法完成。然而,一旦异步方法完成,它必须等待原始调用者完成后才能继续。他们都在等待对方完成,而且永远不会。通过在调用中使用configurewait (false), async方法将能够在另一个线程上完成自己操作,而不关心自己的状态机的位置,并通知原始线程它已经完成。进行这个调用的最佳实践如下:
1 [HttpPut]
2 public IActionResult Put([FromBody]UpdateCommand command) =>
3 _responseMediator.ExecuteAsync(command).ConfigureAwait(false).GetAwaiter().GetResult();
.NET Standard与ConfigureAwait(false)
在.NETCore中,微软删除了导致我们在任何地方都需要ConfigureAwait(false)的SynchronizationContext。因此,ASP.NETCore应用程序在技术上不需要任何ConfigureAwait(false)逻辑,因为它是多余的。但是,如果在开发有一个使用.NETStandard的库,那么强烈建议仍然使用.ConfigureAwait(false)。在.NETCore中,这自动是无效的。但是如果有.NETFramework的人最终使用这个库并同步调用它,那么它们将会遇到一堆麻烦。但是随着.NET5是由.NETCore构建的,所以未来大多都是.NetCore调用.Netstadard,你如果不准备让.NetFramework调用你的standard库,大可不必兼容。
ConfigureAwait(false) 贯穿始终
如果同步调用有可能调用您的异步方法,那么在整个调用堆栈的每个异步调用上,您都将被迫设置. configureAwait (false) !如果不这样做,就会导致另一个死锁。这里的问题是,每个async/ await对于调用它的当前方法都是本地的。因此,调用链的每个异async/await都可能最终在不同的线程上恢复。如果一个同步调用一路向下,遇到一个没有configurewait(false)的任务,那么这个任务将尝试等待顶部的原始线程完成,然后才能继续。虽然这最终会让你感到心累,因为要检查所有调用是否设置此属性。
开销
虽然async/ await可以极大地增加应用程序一次处理的请求数量,但是使用它是有代价的。每个async/ await调用最终都将创建一个小状态机来跟踪所有信息。虽然这个开销很小,但是如果滥用async/ await,则会导致速度变慢。只有当线程不得不等待结果时,才应该等待它。
Async Void
虽然几乎所有的async / await方法都应返回某种类型的Task,但此规则有一个例外:有时,您可以使用async void。但是,当您使用它时,调用者实际上不会等待该任务完成后才能恢复自己。它实际上是一种即发即忘的东西。有两种情况你想要使用它。
第一种情况是事件处理程序,如WPF或WinForms中的按钮单击。默认情况下,事件处理程序的定义必须为void。如果你把一个任务放在那里,程序将无法编译,并且返回某些东西的事件会感觉很奇怪。如果该按钮调用异步async,则必须执行async void才能使其正常工作。幸运的是,这是我们想要的,因为这种使用不会阻塞UI。
第二个是请求你不介意等待获得结果的东西。最常见的示例是发送日志邮件,但不想等待它完成或者不关心它是否完成。
然而,对于这两种情况,都有一些缺点。首先,调用方法不能try/catch调用中的任何异常。它最终将进入AppDomain UnhandledException事件。不过,如果在实际的async void方法中放入一个try catch,就可以有效地防止这种情况发生。另一个问题是调用者永远不会知道它何时结束,因为它不返回任何东西。因此,如果你关心什么时候完成某个Task,那么实际上需要返回一个Task。
探讨.NetCore中异步注意事项
在.NetCore中已经剔除了SynchronizationContext,剔除他的主要原因主要是性能和进一步简化操作
在.NetCore中我们不用继续关心异步同步混用情况下,是否哪里没有设置ConfigureAwait(false) 会导致的死锁问题,因为在.netcore中的async/await 可能在任何线程上执行,并且可能并行运行!
以下代码为例:
1 private HttpClient _client = new HttpClient();
2
3 async Task<List<string>> GetBothAsync(string url1, string url2)
4 {
5 var result = new List<string>();
6 var task1 = GetOneAsync(result, url1);
7 var task2 = GetOneAsync(result, url2);
8 await Task.WhenAll(task1, task2);
9 return result;
10 }
11
12 async Task GetOneAsync(List<string> result, string url)
13 {
14 var data = await _client.GetStringAsync(url);
15 result.Add(data);
16 }
它下载两个字符串并将它们放入一个List中。此代码在旧版ASP.NET(.NetFramework)中工作正常,由于请求处设置了await,请求上下文一次只允许一个连接.
其中result.Add(data)
一次只能由一个线程执行,因为它在请求上下文中执行。
但是,这个相同的代码在ASP.NET Core上是不安全的; 具体地说,该result.Add(data)
行可以由两个线程同时执行,而不保护共享List<string>
。
所以在.Netcore中要特别注意异步代码在并行执行情况下引发的问题
参考:https://stackoverflow.com/questions/31186354/async-await-where-is-continuation-of-awaitable-part-of-method-performed
async-await – async / await防止Angular2在模板语句中使用时呈现组件
async onClickButton() { await this.shoppingCartService.add(this.selectedOffer); this.router.navigate(['ShoppingCartComponent']); }
数据将添加到购物车,但在导航到下一页时,只会呈现标题,而数据则不会.此方法有效,如果不使用async-await,将正确呈现以下页面.
使用ChangeDetectorRef.detectChanges()和ApplicationRef.tick()强制更改检测无效.
离开下一页即ShoppingCartComponent后,将进行渲染,并暂时显示数据.
什么想法可能会出错?
解决方法
作为解决方法,您需要在构造函数中注入ngzone并将代码更改为
async onClickButton() { await this.shoppingCartService.add(this.selectedOffer); this.ngzone.run(() => { this.router.navigate(['ShoppingCartComponent']); }); }
另见https://github.com/angular/angular/issues/322
我们今天的关于“Fire and forget” python async/await的分享已经告一段落,感谢您的关注,如果您想了解更多关于.net – 使用Task.Wait()代码包装Async / Await IAsyncOperations有什么风险?、asp.net – Async / Await和AsyncController?、Async,Await和ConfigureAwait的关系、async-await – async / await防止Angular2在模板语句中使用时呈现组件的相关信息,请在本站查询。
在这篇文章中,我们将为您详细介绍Android MediaRecording错误启动失败-19 runTimeException的内容,并且讨论关于error launching android studio的相关问题。此外,我们还会涉及一些关于Android FATAL EXCEPTION MAIN:java.lang.RuntimeException:无法启动活动ComponentInfo、Android java.lang.RuntimeException:无法实例化活动ComponentInfo … java.lang.NullPointerException、Android Proguard ExceptionInInitializerError和RuntimeException、Android Robolectric – ContentProvider中queryBuilder.query()中的RuntimeException / InstantiationException的知识,以帮助您更全面地了解这个主题。
本文目录一览:- Android MediaRecording错误启动失败-19 runTimeException(error launching android studio)
- Android FATAL EXCEPTION MAIN:java.lang.RuntimeException:无法启动活动ComponentInfo
- Android java.lang.RuntimeException:无法实例化活动ComponentInfo … java.lang.NullPointerException
- Android Proguard ExceptionInInitializerError和RuntimeException
- Android Robolectric – ContentProvider中queryBuilder.query()中的RuntimeException / InstantiationException
Android MediaRecording错误启动失败-19 runTimeException(error launching android studio)
我的媒体录制出现问题。我正在尝试使用前置摄像头进行记录。这给我一个错误(但预览正常)。每当我使用后置摄像头时,一切正常,我觉得这很奇怪。可能是什么问题,可能是解决方案?我的代码和错误如下所示。
编辑。使用VGA前置摄像头录制似乎不起作用。这怎么可能?虽然可以使用HTC camera应用程序进行录制。
预先感谢您。
protected void startRecording() throws Exception { mrec = new MediaRecorder(); mCamera.unlock(); mrec.setCamera(mCamera); mrec.setVideoSource(MediaRecorder.VideoSource.CAMERA); mrec.setAudioSource(MediaRecorder.AudioSource.MIC); mrec.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH)); //mrec.setPreviewDisplay(surfaceHolder.getSurface()); File picDirectory = new File(Environment.getExternalStorageDirectory() +"/TrouwApp"); picDirectory.mkdirs(); File mediaStorageDir = new File(Environment.getExternalStorageDirectory() +"/TrouwApp", "Videos"); // Create the storage directory if it does not exist if (! mediaStorageDir.exists()){ if (! mediaStorageDir.mkdirs()){ Log.d("MyCameraApp", "failed to create directory"); } } mrec.setOutputFile( mediaStorageDir.getPath() + File.separator + date + "_" + videonr+ ".3gp"); mrec.prepare(); mrec.start();//line 136 Log.d(TAG, "Recording started!!");}
行添加到清单:
<uses-feature android:name="android.hardware.camera" /><uses-permission android:name="android.permission.RECORD_AUDIO" /><uses-permission android:name="android.permission.CAMERA" /><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
错误日志:
08-25 23:25:25.332:V / MediaRecorderJNI(4989):设置08-25 23:25:25.362:V / MediaRecorder(4989):构造函数08-25 23:25:25.402:V / MediaRecorder(4989):doCleanUp08-25 23:25:25.402:V / MediaRecorder(4989):setListener08-25 23:25:25.402:V / MediaRecorderJNI(4989):setMediaRecorder E:mr = mr08-25 23:25:25.402:V / MediaRecorderJNI(4989):setMediaRecorder X08-25 23:25:25.402:V / MediaRecorderJNI(4989):getMediaRecorder E08-25 23:25:25.402:V / MediaRecorderJNI(4989):JNIMediaRecorderListener :: setCamera08-25 23:25:25.402:V / MediaRecorder(4989):setCamera(0x16c2290,0x1c08dc8)08-25 23:25:25.402:V / MediaRecorderJNI(4989):process_media_recorder_call08-25 23:25:25.402:V / MediaRecorderJNI(4989):setVideoSource(1)08-25 23:25:25.402:V / MediaRecorderJNI(4989):getMediaRecorder E08-25 23:25:25.402:V / MediaRecorder(4989):setVideoSource(1)08-25 23:25:25.402:V / MediaRecorder(4989):由于媒体记录器尚未初始化,请调用init()08-25 23:25:25.402:V / MediaRecorder(4989):初始化08-25 23:25:25.412:V / MediaRecorderJNI(4989):process_media_recorder_call08-25 23:25:25.412:V / MediaRecorderJNI(4989):setAudioSource(1)08-25 23:25:25.412:V / MediaRecorderJNI(4989):getMediaRecorder E08-25 23:25:25.412:V / MediaRecorder(4989):setAudioSource(1)08-25 23:25:25.412:V / MediaRecorderJNI(4989):process_media_recorder_call08-25 23:25:25.502:V / MediaRecorderJNI(4989):setOutputFormat(2)08-25 23:25:25.502:V / MediaRecorderJNI(4989):getMediaRecorder E08-25 23:25:25.502:V / MediaRecorder(4989):setOutputFormat(2)08-25 23:25:25.502:V / MediaRecorderJNI(4989):process_media_recorder_call08-25 23:25:25.502:V / MediaRecorderJNI(4989):setVideoFrameRate(30)08-25 23:25:25.502:V / MediaRecorderJNI(4989):getMediaRecorder E08-25 23:25:25.502:V / MediaRecorder(4989):setVideoFrameRate(30)08-25 23:25:25.502:V / MediaRecorderJNI(4989):process_media_recorder_call08-25 23:25:25.502:V / MediaRecorderJNI(4989):setVideoSize(1920,1088)08-25 23:25:25.502:V / MediaRecorderJNI(4989):getMediaRecorder E08-25 23:25:25.502:V / MediaRecorder(4989):setVideoSize(1920,1088)08-25 23:25:25.502:V / MediaRecorderJNI(4989):process_media_recorder_call08-25 23:25:25.502:V / MediaRecorderJNI(4989):setParameter()08-25 23:25:25.502:V / MediaRecorderJNI(4989):getMediaRecorder E08-25 23:25:25.502:V / MediaRecorder(4989):setParameters(视频参数编码比特率= 12000000)08-25 23:25:25.512:V / MediaRecorderJNI(4989):process_media_recorder_call08-25 23:25:25.512:V / MediaRecorderJNI(4989):setVideoEncoder(2)08-25 23:25:25.512:V / MediaRecorderJNI(4989):getMediaRecorder E08-25 23:25:25.512:V / MediaRecorder(4989):setVideoEncoder(2)08-25 23:25:25.512:V / MediaRecorderJNI(4989):process_media_recorder_call08-25 23:25:25.512:V / MediaRecorderJNI(4989):setParameter()08-25 23:25:25.512:V / MediaRecorderJNI(4989):getMediaRecorder E08-25 23:25:25.512:V / MediaRecorder(4989):setParameters(音频参数编码比特率= 96000)08-25 23:25:25.512:V / MediaRecorderJNI(4989):process_media_recorder_call08-25 23:25:25.512:V / MediaRecorderJNI(4989):setParameter()08-25 23:25:25.512:V / MediaRecorderJNI(4989):getMediaRecorder E08-25 23:25:25.512:V / MediaRecorder(4989):setParameters(音频参数通道数= 1)08-25 23:25:25.512:V / MediaRecorderJNI(4989):process_media_recorder_call08-25 23:25:25.512:V / MediaRecorderJNI(4989):setParameter()08-25 23:25:25.512:V / MediaRecorderJNI(4989):getMediaRecorder E08-25 23:25:25.512:V / MediaRecorder(4989):setParameters(音频参数采样率= 48000)08-25 23:25:25.512:V / MediaRecorderJNI(4989):process_media_recorder_call08-25 23:25:25.512:V / MediaRecorderJNI(4989):setAudioEncoder(3)08-25 23:25:25.512:V / MediaRecorderJNI(4989):getMediaRecorder E08-25 23:25:25.512:V / MediaRecorder(4989):setAudioEncoder(3)08-25 23:25:25.512:V / MediaRecorderJNI(4989):process_media_recorder_call08-25 23:25:25.542:V / MediaRecorderJNI(4989):setOutputFile08-25 23:25:25.542:V / MediaRecorderJNI(4989):getMediaRecorder E08-25 23:25:25.542:V / MediaRecorder(4989):setOutputFile(60,0,0)08-25 23:25:25.542:V / MediaRecorderJNI(4989):process_media_recorder_call08-25 23:25:25.542:V / MediaRecorderJNI(4989):准备08-25 23:25:25.542:V / MediaRecorderJNI(4989):getMediaRecorder E08-25 23:25:25.542:V / MediaRecorder(4989):准备08-25 23:25:25.542:V / MediaRecorderJNI(4989):process_media_recorder_call08-25 23:25:25.542:V / MediaRecorderJNI(4989):开始08-25 23:25:25.552:V / MediaRecorderJNI(4989):getMediaRecorder E08-25 23:25:25.552:V / MediaRecorder(4989):开始08-25 23:25:25.562:E / MediaRecorder(4989):启动失败:-1908-25 23:25:25.562:V / MediaRecorderJNI(4989):process_media_recorder_call08-25 23:25:25.562:E / MediaRecorder(4989):启动失败08-25 23:25:25.562:E / MediaRecorder(4989):尝试删除损坏的文件:/mnt/sdcard/TrouwApp/Videos/25-8-2013_0.3gp08-25 23:25:25.562:D / videoActivity(4989):错误启动失败。08-25 23:25:25.562:D / videoActivity(4989):错误java.lang.RuntimeException:启动失败。08-25 23:25:25.562:D / videoActivity(4989):错误java.lang.RuntimeException:启动失败。08-25 23:25:25.562:V / MediaRecorderJNI(4989):发布08-25 23:25:25.562:V / MediaRecorderJNI(4989):setMediaRecorder E:mr = null08-25 23:25:25.562:V / MediaRecorderJNI(4989):setMediaRecorder X08-25 23:25:25.562:V / MediaRecorder(4989):setListener08-25 23:25:25.562:V / MediaRecorder(4989):发布08-25 23:25:25.562:V / MediaRecorder(4989):析构函数08-25 23:25:25.562:D / videoActivity(4989):开始记录错误08-25 23:25:25.562:W / System.err(4989):java.lang.RuntimeException:启动失败。08-25 23:25:25.572:W / System.err(4989):位于android.media.MediaRecorder._start(本机方法)08-25 23:25:25.572:W / System.err(4989):位于android.media.MediaRecorder.start(MediaRecorder.java:712)08-25 23:25:25.572:W / System.err(4989):在com.example.trouwapp.VideoActivity.startRecording(VideoActivity.java:136)08-25 23:25:25.572:W / System.err(4989):在com.example.trouwapp.VideoActivity.onClick(VideoActivity.java:246)08-25 23:25:25.572:W / System.err(4989):在android.view.View.performClick(View.java:3549)08-25 23:25:25.572:W / System.err(4989):在android.view.View $ PerformClick.run(View.java:14393)08-25 23:25:25.582:W / System.err(4989):位于android.os.Handler.handleCallback(Handler.java:605)08-25 23:25:25.582:W / System.err(4989):在android.os.Handler.dispatchMessage(Handler.java:92)08-25 23:25:25.582:W / System.err(4989):位于android.os.Looper.loop(Looper.java:154)08-25 23:25:25.582:W / System.err(4989):位于android.app.ActivityThread.main(ActivityThread.java:4945)08-25 23:25:25.582:W / System.err(4989):at java.lang.reflect.Method.invokeNative(本机方法)08-25 23:25:25.582:W / System.err(4989):at java.lang.reflect.Method.invoke(Method.java:511)08-25 23:25:25.582:W / System.err(4989):在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:784)08-25 23:25:25.582:W / System.err(4989):在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)08-25 23:25:25.592:W / System.err(4989):在dalvik.system.NativeStart.main(本机方法)08-25 23:25:55.582:V / MediaRecorderJNI(4989):native_reset08-25 23:25:55.582:V / MediaRecorderJNI(4989):getMediaRecorder E08-25 23:25:55.582:V / MediaRecorderJNI(4989):发布08-25 23:25:55.582:V / MediaRecorderJNI(4989):setMediaRecorder E:mr = null08-25 23:25:55.582:V / MediaRecorderJNI(4989):setMediaRecorder X08-25 23:25:56.002:D / AndroidRuntime(4989):关闭VM08-25 23:25:56.002:W / dalvikvm(4989):threadid = 1:线程以未捕获的异常退出(group = 0x40ac8228)
答案1
小编典典找到了解决方案。由于我使用的是前置摄像头,因此我需要从前置摄像头获取摄像机配置文件。我做到了这一点:
mrec.setProfile(CamcorderProfile.get(1, CamcorderProfile.QUALITY_HIGH));
代替这个:
mrec.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
Android FATAL EXCEPTION MAIN:java.lang.RuntimeException:无法启动活动ComponentInfo
我是编程android的nubie,我知道这里有4m是很多页面为我的问题打乱解决方案,但现在我输了2天仍然没有得到解决方案.请帮我!
首先是我的错误:
01-02 11:08:27.314: D/AndroidRuntime(1045): Shutting down VM
01-02 11:08:27.314: W/dalvikvm(1045): threadid=1: thread exiting with uncaught exception (group=0x409e61f8)
01-02 11:08:27.324: E/AndroidRuntime(1045): FATAL EXCEPTION: main
01-02 11:08:27.324: E/AndroidRuntime(1045): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.wifiscan/com.example.wifiscan.activity_wifi_scan}: java.lang.classNotFoundException: com.example.wifiscan.activity_wifi_scan
01-02 11:08:27.324: E/AndroidRuntime(1045): at android.app.ActivityThread.performlaunchActivity(ActivityThread.java:1880)
01-02 11:08:27.324: E/AndroidRuntime(1045): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
01-02 11:08:27.324: E/AndroidRuntime(1045): at android.app.ActivityThread.access$600(ActivityThread.java:123)
01-02 11:08:27.324: E/AndroidRuntime(1045): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
01-02 11:08:27.324: E/AndroidRuntime(1045): at android.os.Handler.dispatchMessage(Handler.java:99)
01-02 11:08:27.324: E/AndroidRuntime(1045): at android.os.Looper.loop(Looper.java:137)
01-02 11:08:27.324: E/AndroidRuntime(1045): at android.app.ActivityThread.main(ActivityThread.java:4424)
01-02 11:08:27.324: E/AndroidRuntime(1045): at java.lang.reflect.Method.invokeNative(Native Method)
01-02 11:08:27.324: E/AndroidRuntime(1045): at java.lang.reflect.Method.invoke(Method.java:511)
01-02 11:08:27.324: E/AndroidRuntime(1045): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
01-02 11:08:27.324: E/AndroidRuntime(1045): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
01-02 11:08:27.324: E/AndroidRuntime(1045): at dalvik.system.NativeStart.main(Native Method)
01-02 11:08:27.324: E/AndroidRuntime(1045): Caused by: java.lang.classNotFoundException: com.example.wifiscan.activity_wifi_scan
01-02 11:08:27.324: E/AndroidRuntime(1045): at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:61)
01-02 11:08:27.324: E/AndroidRuntime(1045): at java.lang.classLoader.loadClass(ClassLoader.java:501)
01-02 11:08:27.324: E/AndroidRuntime(1045): at java.lang.classLoader.loadClass(ClassLoader.java:461)
01-02 11:08:27.324: E/AndroidRuntime(1045): at android.app.Instrumentation.newActivity(Instrumentation.java:1023)
01-02 11:08:27.324: E/AndroidRuntime(1045): at android.app.ActivityThread.performlaunchActivity(ActivityThread.java:1871)
01-02 11:08:27.324: E/AndroidRuntime(1045): ... 11 more
我的WifiScan:
public class WifiScan extends Activity implements OnClickListener {
WifiManager wifi;
ListView lv;
TextView textStatus;
Button buttonScan;
int size = 0;
List<ScanResult> results;
String ITEM_KEY = "key";
ArrayList<HashMap<String, String>> arraylist = new ArrayList<HashMap<String, String>>();
SimpleAdapter adapter;
/* Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_wifi_scan);
buttonScan = (Button) findViewById(R.id.scan);
buttonScan.setonClickListener(this);
lv = (ListView)findViewById(R.id.list);
wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
if (wifi.isWifiEnabled() == false)
{
Toast.makeText(getApplicationContext(), "wifi is disabled..making it enabled", Toast.LENGTH_LONG).show();
wifi.setWifiEnabled(true);
}
wifi.startScan(); //js dopisal
// this.adapter = new SimpleAdapter(WiFiDemo.this, arraylist, R.layout.row, new String[] { ITEM_KEY }, new int[] { R.id.list_value });
lv.setAdapter(this.adapter);
registerReceiver(new broadcastReceiver()
{
@Override
public void onReceive(Context c, Intent intent)
{
results = wifi.getScanResults();
size = results.size();
}
}, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
}
public void onClick(View view)
{
arraylist.clear();
wifi.startScan();
Toast.makeText(this, "Scanning...." + size, Toast.LENGTH_SHORT).show();
try
{
size = size - 1;
while (size >= 0)
{
HashMap<String, String> item = new HashMap<String, String>();
item.put(ITEM_KEY, results.get(size).SSID + " " + results.get(size).capabilities);
arraylist.add(item);
size--;
adapter.notifyDataSetChanged();
}
}
catch (Exception e)
{ }
}
}
我的activity_wifi_scan.xml文件:
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/TableLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".WifiScan" >
<Button
android:id="@+id/scan"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="scan"
android:text="SCAN" />
<ListView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
</TableLayout>
和我的AndroidManifest文件:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.wifiscan"
android:versionCode="1"
android:versionName="1.0" >
<uses-premission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>
<uses-permission android:name="android.permission.READ_PHONE_STATE"> </uses-permission>
<uses-permission android:name="android.permission.INTERNET"> </uses-permission>
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity android:name=".activity_wifi_scan">
<intent-filter>
<action android:name="android.intent.action.MAIN"></action>
<category android:name="android.intent.category.LAUNCHER"></category>
<data />
</intent-filter>
</activity>
<receiver android:name=".activity_wifi_scan">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER"/>
<action android:name="android.net.wifi.WIFI_STATE_CHANGED"/>
</intent-filter>
</receiver>
</application>
</manifest>
解决方法:
您的活动名称是WifiScan但您已将其声明为.activity_wifi_scan更改它并重试.
更改<活动>要素:
<activity android:name=".WifiScan">
<intent-filter>
<action android:name="android.intent.action.MAIN"></action>
<category android:name="android.intent.category.LAUNCHER"></category>
<data />
</intent-filter>
</activity>
Android java.lang.RuntimeException:无法实例化活动ComponentInfo … java.lang.NullPointerException
出于某种原因,每次尝试启动我的应用程序时,我都会出现以下错误:
Unable to instantiate activity ComponentInfo{com.example.lifeahead/com.example.lifeahead.MainActivity}:java.lang.NullPointerException
我检查了清单文件,并添加了所有活动.
我启动应用程序时使用的唯一方法是:
private void logIn(){
Button logIn = (Button) findViewById(R.id.login);
logIn.setonClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Todo Auto-generated method stub
Intent loginIntent = new Intent(MainActivity.this, HomeActivity.class);
loginIntent.putExtra("cmUN", cmUN);
loginIntent.putExtra("cmPW", cmPW);
startActivity(loginIntent);
}
});
}
这是onCreate:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment()).commit();
}
logIn();
}
完整日志:
Ë
/AndroidRuntime(1607): FATAL EXCEPTION: main
E/AndroidRuntime(1607): Process: com.example.lifeahead, PID: 1607
E/AndroidRuntime(1607): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.lifeahead/com.example.lifeahead.MainActivity}: java.lang.NullPointerException
E/AndroidRuntime(1607): at android.app.ActivityThread.performlaunchActivity(ActivityThread.java:2121)
E/AndroidRuntime(1607): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
E/AndroidRuntime(1607): at android.app.ActivityThread.access$800(ActivityThread.java:135)
E/AndroidRuntime(1607): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
E/AndroidRuntime(1607): at android.os.Handler.dispatchMessage(Handler.java:102)
E/AndroidRuntime(1607): at android.os.Looper.loop(Looper.java:136)
E/AndroidRuntime(1607): at android.app.ActivityThread.main(ActivityThread.java:5017)
E/AndroidRuntime(1607): at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(1607): at java.lang.reflect.Method.invoke(Method.java:515)
E/AndroidRuntime(1607): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
E/AndroidRuntime(1607): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
E/AndroidRuntime(1607): at dalvik.system.NativeStart.main(Native Method)
E/AndroidRuntime(1607): Caused by: java.lang.NullPointerException
E/AndroidRuntime(1607): at android.app.Activity.findViewById(Activity.java:1884)
E/AndroidRuntime(1607): at com.example.lifeahead.MainActivity.<init>(MainActivity.java:22)
E/AndroidRuntime(1607): at java.lang.class.newInstanceImpl(Native Method)
E/AndroidRuntime(1607): at java.lang.class.newInstance(Class.java:1208)
E/AndroidRuntime(1607): at android.app.Instrumentation.newActivity(Instrumentation.java:1061)
E/AndroidRuntime(1607): at android.app.ActivityThread.performlaunchActivity(ActivityThread.java:2112)
E/AndroidRuntime(1607): ... 11 more
我感谢所有帮助!
解决方法:
stacktrace告诉你
Button logIn = (Button) findViewById(R.id.login);
findViewById返回的对象为null,因为您拥有的唯一方法是logIn(). findViewById返回null的唯一原因是因为您正在查找不属于当前活动的视图层次结构的视图
Android Proguard ExceptionInInitializerError和RuntimeException
我想混淆我的.apk,我和Proguard有些麻烦.使用eclipse我启用了这个:
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
我正在使用4个外部库:
> android-support-v4.jar
>九岁的android-lib.jar
> gson-2.2.2.jar
> commons-io-2.4.jar
我想我在使用gson时遇到了麻烦:
private static Type MY_DATA_TYPE = new Typetoken<Pair<Map<Point, Void>, Integer>>() {}.getType();
我每次使用它:
FATAL EXCEPTION: main
java.lang.ExceptionInInitializerError at com.myapp.MyActivity.onCreate(UnkNown Source)
...
Caused by: java.lang.RuntimeException: Missing type parameter.
at com.google.gson.reflect.Typetoken.getSuperclasstypeParameter(UnkNown Source)
at com.google.gson.reflect.Typetoken.<init>(UnkNown Source)
我正在使用这个选项,但我想它不会有帮助:
-keepattributes Exceptions, InnerClasses, *Annotation*, EnclosingMethod
-dontskipnonpubliclibraryclassmembers
-libraryjars .../libs/android-support-v4.jar
-libraryjars .../libs/nine-old-android-lib.jar
-libraryjars .../libs/gson-2.2.2.jar
-libraryjars .../libs/commons-io-2.4.jar
-keep class java.** { *; }
-keep class android.** { *; }
-keep class org.** { *; }
-keep class com.google.** { *; }
-keep class com.facebook.** { *; }
-keep class com.nineoldandroids.** { *; }
我该如何解决这个问题并创建一个可以正常工作的混淆的.apk?
谢谢你的时间.
解决方法:
猜猜这是一个gson“问题”,这是解决方案:
-keepattributes Signature
-keep class sun.misc.Unsafe { *; }
-keep class com.google.gson.examples.android.model.** { *; }
感谢https://groups.google.com/forum/#!topic/google-gson/6XuHfOoZIKo
Android Robolectric – ContentProvider中queryBuilder.query()中的RuntimeException / InstantiationException
正在测试的方法在实际应用中起作用!
这是API 17 r2和RoboLectric:
robolectric-2.0-α-3-20130417.013705-46-罐与 – dependencies.jar
@Override public Cursor query(Uri uri,String[] projection,String selection,String[] selectionArgs,String sortOrder) { Log.d(Constants.TAG,"MyContentProvider.query()"); switch(matcher.match(uri)) { case ITEM: // OK selection = "_id = ?"; selectionArgs = new String[]{ Long.toString(ContentUris.parseId(uri)) }; case ITEMS: // OK break; default: throw new IllegalArgumentException("Did not recognize URI " + uri); } // build the query with sqliteQueryBuilder sqliteQueryBuilder qBuilder = new sqliteQueryBuilder(); qBuilder.setTables(TABLE_NAME); // query the database and get result in cursor final sqliteDatabase db = mDatabase.getReadableDatabase(); Cursor resultCursor = qBuilder.query(db,// Line 112 in trace projection,selection,selectionArgs,null,sortOrder,null); resultCursor.setNotificationUri(getContext().getContentResolver(),uri); return resultCursor; }
这是追溯:
java.lang.RuntimeException: java.lang.InstantiationException at org.robolectric.bytecode.ShadowWrangler.createShadowFor(ShadowWrangler.java:300) at org.robolectric.bytecode.ShadowWrangler.initializing(ShadowWrangler.java:74) at org.robolectric.bytecode.RobolectricInternals.initializing(RobolectricInternals.java:90) at android.database.sqlite.sqliteQuery.$$robo$init(sqliteQuery.java) at android.database.sqlite.sqliteClosable.<init>(sqliteClosable.java:26) at android.database.sqlite.sqliteProgram.<init>(sqliteProgram.java:41) at android.database.sqlite.sqliteQuery.<init>(sqliteQuery.java:37) at android.database.sqlite.sqliteDirectCursorDriver.query(sqliteDirectCursorDriver.java:44) at android.database.sqlite.sqliteDatabase.rawQueryWithFactory(sqliteDatabase.java:1314) at android.database.sqlite.sqliteQueryBuilder.query(sqliteQueryBuilder.java:400) at android.database.sqlite.sqliteQueryBuilder.query(sqliteQueryBuilder.java:333) at com.example.readingsprovider.ReadingsContentProvider.query(ReadingsContentProvider.java:112) at com.example.readingsprovider.test.ContentProviderTest.testUpdateMultipleWithoutWhere(ContentProviderTest.java:110) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20) at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:267) at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79) at org.junit.runners.BlockJUnit4ClassRunner.runchild(BlockJUnit4ClassRunner.java:71) at org.junit.runners.BlockJUnit4ClassRunner.runchild(BlockJUnit4ClassRunner.java:49) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52) at org.junit.runners.ParentRunner.runchildren(ParentRunner.java:191) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184) at org.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:202) at org.junit.runners.ParentRunner.run(ParentRunner.java:236) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) Caused by: java.lang.InstantiationException at sun.reflect.InstantiationExceptionConstructorAccessorImpl.newInstance(InstantiationExceptionConstructorAccessorImpl.java:30) at java.lang.reflect.Constructor.newInstance(Constructor.java:513) at java.lang.class.newInstance0(Class.java:357) at java.lang.class.newInstance(Class.java:310) at org.robolectric.bytecode.ShadowWrangler.createShadowFor(ShadowWrangler.java:293) at org.robolectric.bytecode.ShadowWrangler.initializing(ShadowWrangler.java:74) at org.robolectric.bytecode.RobolectricInternals.initializing(RobolectricInternals.java:90) at android.database.sqlite.sqliteQuery.$$robo$init(sqliteQuery.java) at android.database.sqlite.sqliteClosable.<init>(sqliteClosable.java:26) at android.database.sqlite.sqliteProgram.<init>(sqliteProgram.java:41) at android.database.sqlite.sqliteQuery.<init>(sqliteQuery.java:37) at android.database.sqlite.sqliteDirectCursorDriver.$$robo$$sqliteDirectCursorDriver_7ac1_query(sqliteDirectCursorDriver.java:44) at android.database.sqlite.sqliteDirectCursorDriver.query(sqliteDirectCursorDriver.java) at android.database.sqlite.sqliteDatabase.$$robo$$sqliteDatabase_ab15_rawQueryWithFactory(sqliteDatabase.java:1314) at android.database.sqlite.sqliteDatabase.rawQueryWithFactory(sqliteDatabase.java) at android.database.sqlite.sqliteQueryBuilder.$$robo$$sqliteQueryBuilder_ba4d_query(sqliteQueryBuilder.java:400) at android.database.sqlite.sqliteQueryBuilder.query(sqliteQueryBuilder.java) at android.database.sqlite.sqliteQueryBuilder.$$robo$$sqliteQueryBuilder_ba4d_query(sqliteQueryBuilder.java:333) at android.database.sqlite.sqliteQueryBuilder.query(sqliteQueryBuilder.java) at com.example.readingsprovider.ReadingsContentProvider.query(ReadingsContentProvider.java:112) at com.example.readingsprovider.test.ContentProviderTest.testUpdateMultipleWithoutWhere(ContentProviderTest.java:110) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) ... 21 more
可以告诉我这是否是Robolectric的限制,还是我的不好?非常感谢!
附:如果Reflection API将失败的类名放在InstantiationException消息中,难道不是梦幻般的吗?
解决方法
1.创建自定义sqliteShadow
@Implements(value = sqliteDatabase.class,inheritImplementationMethods = true) public class CustomsqliteShadow extends ShadowsqliteDatabase { @Implementation public Cursor rawQueryWithFactory (sqliteDatabase.CursorFactory cursorFactory,String sql,String editTable,CancellationSignal cancellationSignal) { return rawQueryWithFactory(cursorFactory,sql,editTable); } }
2.将@Config注释添加到测试中
要使用自定义阴影类,可以在robolectric2中使用@Config注释
@RunWith(RobolectricTestRunner.class) @Config( shadows = {CustomsqliteShadow.class}) public class ContentProviderTest {
参考
http://robolectric.blogspot.co.at/2013/05/configuring-robolectric-20.html
关于Android MediaRecording错误启动失败-19 runTimeException和error launching android studio的问题我们已经讲解完毕,感谢您的阅读,如果还想了解更多关于Android FATAL EXCEPTION MAIN:java.lang.RuntimeException:无法启动活动ComponentInfo、Android java.lang.RuntimeException:无法实例化活动ComponentInfo … java.lang.NullPointerException、Android Proguard ExceptionInInitializerError和RuntimeException、Android Robolectric – ContentProvider中queryBuilder.query()中的RuntimeException / InstantiationException等相关内容,可以在本站寻找。
本文将带您了解关于Spring依赖注入到Spring TestExecutionListeners中不起作用的新内容,同时我们还将为您解释spring依赖注入实例的相关知识,另外,我们还将为您提供关于2. 1 SpringBoot 启动流程 - SpringApplicationRunListener-Listener 初始化、2. SpringBoot 启动流程 - SpringApplicationRunListener、@TestExecutionListeners似乎禁用了自动装配或上下文加载、asp.net-mvc – OnActionExecuting(FilterExecutingContext)不再存在于System.Web.Mvc中?的实用信息。
本文目录一览:- Spring依赖注入到Spring TestExecutionListeners中不起作用(spring依赖注入实例)
- 2. 1 SpringBoot 启动流程 - SpringApplicationRunListener-Listener 初始化
- 2. SpringBoot 启动流程 - SpringApplicationRunListener
- @TestExecutionListeners似乎禁用了自动装配或上下文加载
- asp.net-mvc – OnActionExecuting(FilterExecutingContext)不再存在于System.Web.Mvc中?
Spring依赖注入到Spring TestExecutionListeners中不起作用(spring依赖注入实例)
如何将Spring依赖注入到我编写的扩展AbstractTestExecutionListener的TestExecutionListener类中?
Spring DI似乎不适用于TestExecutionListener类。问题示例:
AbstractTestExecutionListener:
class SimpleClassTestListener extends AbstractTestExecutionListener { @Autowired protected String simplefield; // does not work simplefield = null @Override public void beforeTestClass(TestContext testContext) throws Exception { System.out.println("simplefield " + simplefield); }}
配置文件:
@Configuration@ComponentScan(basePackages = { "com.example*" })class SimpleConfig { @Bean public String simpleField() { return "simpleField"; }}
JUnit测试文件:
@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(classes = { SimpleConfig.class })@TestExecutionListeners(mergeMode = TestExecutionListeners.MergeMode.MERGE_WITH_DEFAULTS, listeners = { SimpleClassTestListener.class })public class SimpleTest { @Test public void test(){ assertTrue(); }}
如代码注释中突出显示的那样,当我运行此代码时,它将打印“ simplefield null”,因为simplefield永远不会注入值。
答案1
小编典典只需为整个TestExecutionListener添加自动装配。
@Overridepublic void beforeTestClass(TestContext testContext) throws Exception { testContext.getApplicationContext() .getAutowireCapableBeanFactory() .autowireBean(this); // your code that uses autowired fields}
检查github中的示例项目。
2. 1 SpringBoot 启动流程 - SpringApplicationRunListener-Listener 初始化
返回 SpringApplication 初始化类可以看到这么一句
this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
getSpringFactoriesInstances
private <T> Collection<T> getSpringFactoriesInstances(Class<T> type) {
return this.getSpringFactoriesInstances(type, new Class[0]);
}
private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) {
ClassLoader classLoader = this.getClassLoader();
Set<String> names = new LinkedHashSet(SpringFactoriesLoader.loadFactoryNames(type, classLoader));
List<T> instances = this.createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);
AnnotationAwareOrderComparator.sort(instances);
return instances;
}
SpringFactoriesLoader
这是一个普通的类 属性有下面三个
public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";
private static final Log logger = LogFactory.getLog(SpringFactoriesLoader.class);
private static final Map<ClassLoader, MultiValueMap<String, String>> cache = new ConcurrentReferenceHashMap();
看到了一个不得了的文件 META-INF/spring.factories,这个文件非常非常重要 很多配置都在这里
spring.factories
看看 springboot 源码里这个文件里都有啥吧
# PropertySource Loaders
org.springframework.boot.env.PropertySourceLoader=\
org.springframework.boot.env.PropertiesPropertySourceLoader,\
org.springframework.boot.env.YamlPropertySourceLoader
# Run Listeners
org.springframework.boot.SpringApplicationRunListener=\
org.springframework.boot.context.event.EventPublishingRunListener
# Error Reporters
org.springframework.boot.SpringBootExceptionReporter=\
org.springframework.boot.diagnostics.FailureAnalyzers
# Application Context Initializers
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer,\
org.springframework.boot.context.ContextIdApplicationContextInitializer,\
org.springframework.boot.context.config.DelegatingApplicationContextInitializer,\
org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer
# Application Listeners
org.springframework.context.ApplicationListener=\
org.springframework.boot.ClearCachesApplicationListener,\
org.springframework.boot.builder.ParentContextCloserApplicationListener,\
org.springframework.boot.context.FileEncodingApplicationListener,\
org.springframework.boot.context.config.AnsiOutputApplicationListener,\
org.springframework.boot.context.config.ConfigFileApplicationListener,\
org.springframework.boot.context.config.DelegatingApplicationListener,\
org.springframework.boot.context.logging.ClasspathLoggingApplicationListener,\
org.springframework.boot.context.logging.LoggingApplicationListener,\
org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener
# Environment Post Processors
org.springframework.boot.env.EnvironmentPostProcessor=\
org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor,\
org.springframework.boot.env.SpringApplicationJsonEnvironmentPostProcessor,\
org.springframework.boot.env.SystemEnvironmentPropertySourceEnvironmentPostProcessor
# Failure Analyzers
org.springframework.boot.diagnostics.FailureAnalyzer=\
org.springframework.boot.diagnostics.analyzer.BeanCurrentlyInCreationFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.BeanDefinitionOverrideFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.BeanNotOfRequiredTypeFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.BindFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.BindValidationFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.UnboundConfigurationPropertyFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.ConnectorStartFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.NoSuchMethodFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.NoUniqueBeanDefinitionFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.PortInUseFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.ValidationExceptionFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.InvalidConfigurationPropertyNameFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.InvalidConfigurationPropertyValueFailureAnalyzer
# FailureAnalysisReporters
org.springframework.boot.diagnostics.FailureAnalysisReporter=\
org.springframework.boot.diagnostics.LoggingFailureAnalysisReporter
这么一堆 各种熟悉的名词都在这 SpringApplicationRunListener、ApplicationContextInitializer、ApplicationListener、PropertySourceLoader
loadFactoryNames(type, classLoader)
public static List<String> loadFactoryNames(Class<?> factoryClass, @Nullable ClassLoader classLoader) {
String factoryClassName = factoryClass.getName();
return (List)loadSpringFactories(classLoader).getOrDefault(factoryClassName, Collections.emptyList());
}
private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
MultiValueMap<String, String> result = (MultiValueMap)cache.get(classLoader);
if (result != null) {
return result;
} else {
try {
Enumeration<URL> urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories");
LinkedMultiValueMap result = new LinkedMultiValueMap();
while(urls.hasMoreElements()) {
URL url = (URL)urls.nextElement();
UrlResource resource = new UrlResource(url);
Properties properties = PropertiesLoaderUtils.loadProperties(resource);
Iterator var6 = properties.entrySet().iterator();
while(var6.hasNext()) {
Entry<?, ?> entry = (Entry)var6.next();
String factoryClassName = ((String)entry.getKey()).trim();
String[] var9 = StringUtils.commaDelimitedListToStringArray((String)entry.getValue());
int var10 = var9.length;
for(int var11 = 0; var11 < var10; ++var11) {
String factoryName = var9[var11];
result.add(factoryClassName, factoryName.trim());
}
}
}
cache.put(classLoader, result);
return result;
} catch (IOException var13) {
throw new IllegalArgumentException("Unable to load factories from location [META-INF/spring.factories]", var13);
}
}
}
//todo 这个方法暂且不分析了,大体就是从 spring.factories 里根据 key 取 vale 这里涉及到一个概念 SPI(Service provider Interface),具体请看《SpringBoot-SPI 是个什么东东》
内置 Listener
就是文件里这一堆
2. SpringBoot 启动流程 - SpringApplicationRunListener
按顺序看这两句
SpringApplicationRunListeners listeners = this.getRunListeners(args);
listeners.starting();
listener 一听名字,就知道是一个监听器,监听各种事件的,先看看这个类。
1. SpringApplicationRunListeners
package org.springframework.boot;
class SpringApplicationRunListeners {
private final Log log;
private final List<SpringApplicationRunListener> listeners;
........
public void starting() {
Iterator var1 = this.listeners.iterator();
while(var1.hasNext()) {
SpringApplicationRunListener listener = (SpringApplicationRunListener)var1.next();
listener.starting();
}
}
下面其他的方法差不多
}
是一个 springboot 的内部的类,不对外暴露,里面是一个 SpringApplicationRunListener 的 list,遍历各种 SpringApplicationRunListener 执行相关的监听方法
那就看看 SpringApplicationRunListener 监听了什么事件
2. SpringApplicationRunListener
public interface SpringApplicationRunListener {
//启动
void starting();
//环境准备完毕( 在prepareEnvironment方法内部调用。)
void environmentPrepared(ConfigurableEnvironment environment);
//上下文准备完毕(在prepareContext的开始阶段被调用。)
void contextPrepared(ConfigurableApplicationContext context);
//上下文加载完毕(在prepareContext的最后一步被调用。)
void contextLoaded(ConfigurableApplicationContext context);
//启动完成( 在所有执行完成,ApplicationRunner和CommandLineRunner回调之前。)
void started(ConfigurableApplicationContext context);
//运行中(在run方法最后单独使用try catch执行,只要上面没有异常,项目已经启动完成。那么running回调异常也不能影响正常流程。)
void running(ConfigurableApplicationContext context);
//失败( 在handleRunFailure异常处理中被调用。)
void failed(ConfigurableApplicationContext context, Throwable exception);
}
以下内容,可以再了解整个加载过程后,再来看会更有感触
3. EventPublishingRunListener
springboot 中 SpringApplicationRunListener 的实现类只有这一个
3.1 属性和构造方法
rivate final SpringApplication application;
private final String[] args;
private final SimpleApplicationEventMulticaster initialMulticaster;
public EventPublishingRunListener(SpringApplication application, String[] args) {
this.application = application;
this.args = args;
this.initialMulticaster = new SimpleApplicationEventMulticaster();
Iterator var3 = application.getListeners().iterator();
while(var3.hasNext()) {
ApplicationListener<?> listener = (ApplicationListener)var3.next();
this.initialMulticaster.addApplicationListener(listener);
}
}
3.2 starting
public void starting() {
this.initialMulticaster.multicastEvent(new ApplicationStartingEvent(this.application, this.args));
}
一看这里就涉及了两个关键的东西 一个是 ApplicationEventMulticaster 一个是 ApplicationListener
4. ApplicationEventMulticaster
package org.springframework.context.event;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.core.ResolvableType;
/**
*应用事件多播器ApplicationEventMulticaster的实现可以管理多个应用监听器对象,
*并发布事件到相关监听器。
*应用事件多播器的使用典型场景,应用上下文可以使用应用事件多播器代理事件的发布事件操作。
* @author Rod Johnson
* @author Juergen Hoeller
* @author Stephane Nicoll
*/
public interface ApplicationEventMulticaster {
/**
* 添加监听器
* @param listener the listener to add
*/
void addApplicationListener(ApplicationListener<?> listener);
/**
* 添加监听器bean
* @param listenerBeanName the name of the listener bean to add
*/
void addApplicationListenerBean(String listenerBeanName);
/**
* 移除监听器
* @param listener the listener to remove
*/
void removeApplicationListener(ApplicationListener<?> listener);
/**
* 移除监听器bean
* @param listenerBeanName the name of the listener bean to add
*/
void removeApplicationListenerBean(String listenerBeanName);
/**
* 移除所有注册到多播器的监听器。
* 在移除所有监听器操作调用后,多播器对于发生的事件不做任何处理,直到有新的监听器注册
*/
void removeAllListeners();
/**
* 多播给定的应用事件到相关监听器
* 如果想要尽可能中的支持一般的事件,可以考虑使用{@link #multicastEvent(ApplicationEvent, ResolvableType)}
* 方法。
* @param event the event to multicast
*/
void multicastEvent(ApplicationEvent event);
/**
* Multicast the given application event to appropriate listeners.
* 多播给定的事件到关联监听器。
* 如果eventType类型为空,则将基于event实例 构建一个默认的类型
* @param event the event to multicast
* @param eventType the type of event (can be null)
* @since 4.2
*/
void multicastEvent(ApplicationEvent event, ResolvableType eventType);
}
SimpleApplicationEventMulticaster
ApplicationEventMulticaster 的实现类就这一个 主要是聚合多个 ApplicationListener 批量事件触发 具体详细源码介绍请看 [1]
下面接着看 ApplicationListener
5.ApplicationListener
5.1 Spring 中事件监听器 ApplicationListener
//注:EventListener是java中的接口
@FunctionalInterface
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
void onApplicationEvent(E var1);
}
5.2 Spring 中事件 ApplicationEvent
//EventObject也是java中的类
public abstract class ApplicationEvent extends EventObject {
private static final long serialVersionUID = 7099057708183571937L;
private final long timestamp = System.currentTimeMillis();
public ApplicationEvent(Object source) {
super(source);
}
public final long getTimestamp() {
return this.timestamp;
}
}
监听器主要作用就是在适当的阶段触发适当的操作
5.3 Spring 内置事件类型
- ContextRefreshedEvent ApplicationContext 被初始化或刷新时,该事件被发布。这也可以在 ConfigurableApplicationContext 接口中使用 refresh () 方法来发生。
- ContextStartedEvent 当使用 ConfigurableApplicationContext 接口中的 start () 方法启动 ApplicationContext 时,该事件被发布。你可以调查你的数据库,或者你可以在接受到这个事件后重启任何停止的应用程序。
- ContextStoppedEvent 当使用 ConfigurableApplicationContext 接口中的 stop () 方法停止 ApplicationContext 时,发布这个事件。你可以在接受到这个事件后做必要的清理的工作。
- ContextClosedEvent 当使用 ConfigurableApplicationContext 接口中的 close () 方法关闭 ApplicationContext 时,该事件被发布。一个已关闭的上下文到达生命周期末端;它不能被刷新或重启。
- RequestHandledEvent 这是一个 web-specific 事件,告诉所有 bean HTTP 请求已经被服务。
5.4 springboot 内置事件类型
- starting ApplicationStartingEvent
- environmentPrepared ApplicationEnvironmentPreparedEvent
- contextPrepared ApplicationContextInitializedEvent
- contextLoaded ApplicationPreparedEvent
- started ApplicationStartedEvent
- running ApplicationReadyEvent
- failed ApplicationFailedEvent
初步总结
看到这里就可以知道 springboot 监听机制 就是 SpringApplicationRunListeners 包装了一堆 SpringApplicationRunListener 而 SpringApplicationRunListener 又同时包装了一个 ApplicationEventMulticaster ApplicationEventMulticaster 又包装了一堆 ApplicationListener 最终还是用 ApplicationListener 来实现事件监听
随之而来的问题来了
- listener 从哪里来的?
- 默认都有哪些 listener
#参考网址 1.https://donaldhan.github.io/spring-framework/2018/01/06/SimpleApplicationEventMulticaster%E8%A7%A3%E6%9E%90.html
@TestExecutionListeners似乎禁用了自动装配或上下文加载
如何解决@TestExecutionListeners似乎禁用了自动装配或上下文加载?
我使用以下简单代码跟踪spring integration testing doc:
ListenerTest.java ,入口
b
package learn.spring.test;
import learn.spring.model.Person;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import static org.junit.jupiter.api.Assertions.assertNotNull;
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = SimpleConfig.class)
// @TestExecutionListeners(MyTestExecutionListener.class)
public class ListenerTest {
@Autowired
Person person;
@Test
public void basic() {
assertNotNull(person);
}
}
package learn.spring.test;
import learn.spring.model.Person;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SimpleConfig {
@Bean
public Person rick() {
return new Person("Rick");
}
}
package learn.spring.test;
import lombok.extern.slf4j.Slf4j;
import org.springframework.test.context.TestContext;
import org.springframework.test.context.TestExecutionListener;
@Slf4j
public class MyTestExecutionListener implements TestExecutionListener {
@Override
public void beforeTestExecution(TestContext testContext) throws Exception {
log.info("before {}",testContext.getTestMethod());
}
}
是一个简单的简单POJO,应该安全地省略。
在评论Person
的情况下,测试将通过。但是,@TestExecutionListeners
如果未注释,将失败。
assertNotNull(person);
似乎以某种方式禁用了自动接线。我在做什么错了?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)
asp.net-mvc – OnActionExecuting(FilterExecutingContext)不再存在于System.Web.Mvc中?
protected override void OnActionExecuting(System.Web.Mvc.FilterExecutingContext filterContext)
现在参数是什么?
解决方法
今天关于Spring依赖注入到Spring TestExecutionListeners中不起作用和spring依赖注入实例的讲解已经结束,谢谢您的阅读,如果想了解更多关于2. 1 SpringBoot 启动流程 - SpringApplicationRunListener-Listener 初始化、2. SpringBoot 启动流程 - SpringApplicationRunListener、@TestExecutionListeners似乎禁用了自动装配或上下文加载、asp.net-mvc – OnActionExecuting(FilterExecutingContext)不再存在于System.Web.Mvc中?的相关知识,请在本站搜索。
在本文中,我们将为您详细介绍Maven SonarQube多模块的相关知识,并且为您解答关于maven sonar插件的疑问,此外,我们还会提供一些关于.net持续集成sonarqube篇之 sonarqube与jenkins集成(命令模式)、.net持续集成sonarqube篇之 sonarqube与jenkins集成(插件模式)、.net持续集成sonarqube篇之 sonarqube触发webhook、.net持续集成sonarqube篇之 sonarqube集成单元测试的有用信息。
本文目录一览:- Maven SonarQube多模块(maven sonar插件)
- .net持续集成sonarqube篇之 sonarqube与jenkins集成(命令模式)
- .net持续集成sonarqube篇之 sonarqube与jenkins集成(插件模式)
- .net持续集成sonarqube篇之 sonarqube触发webhook
- .net持续集成sonarqube篇之 sonarqube集成单元测试
Maven SonarQube多模块(maven sonar插件)
我有一个由几个模块组成的项目。
我正在尝试使用SonarQube进行分析。
我在每个模块中都包含了Sonar Maven插件作为依赖项:
<dependency> <groupId>org.codehaus.sonar</groupId> <artifactId>sonar-maven-plugin</artifactId> <version>5.1</version></dependency>
然后我使用以下命令运行Maven:
mvn clean验证声纳:声纳
Maven成功完成,并且可以看到Sonar分析,但是当我打开Sonar UI时,模块在项目中不可见。
然而…
如果我从单个模块目录运行Maven命令,则在项目中可见。
感觉我缺少一些非常简单的东西,感谢您的帮助!
答案1
小编典典而不是作为依赖项,将放在root sonar-maven-plugin
的<build>
部分中pom.xml
,如下所示:
<build> <plugins> <plugin> <groupId>org.sonarsource.scanner.maven</groupId> <artifactId>sonar-maven-plugin</artifactId> <version>3.0.1</version> </plugin> </plugins></build>
并且由于它是一个多模块项目,因此您应该首先从根项目执行安装,然后sonar:sonar
作为专用步骤运行目标,如下所示:
mvn clean installmvn sonar:sonar
要配置声纳服务器URL,请在或中指定一个项目属性,sonar.host.url
如下所示:settings.xml``pom.xml
<properties> <!-- Optional URL to server. Default value is http://localhost:9000 --> <sonar.host.url>http://myserver:9000</sonar.host.url></properties>
.net持续集成sonarqube篇之 sonarqube与jenkins集成(命令模式)
系列目录
Sonarqube结合Jenkins与常见问题
我们引入sonarqube组件的最终目的是要为整个Ci环境服务的,如果不能集成于当前的Jenkins CI,那么我们做的很多关于sonarqube的工作都将是徒劳的.然而这一点几乎不用担心,因为我们从前面的讲解可以看到我们的构建操作都是通过命令行来进进行的,从这一点来看应该是可以无缝的集成到jenkins环境,然而我们把命令原封搬到Jenkins上发现,事情并不像想像的那么简单,而是有各种各样的坑存在.
我们运行以下前面章节运行过的代码,看看会出现什么问题:
MSBuild.SonarQube.Runner.exe begin /k:"mytest" /n:"mytest" /v:"v8.0" /d:sonar.cs.opencover.reportsPaths="%CD%\testcover.xml"
msbuild.exe
"E:\personalproject\newTest2018\ConsoleApp1\packages\OpenCover.4.6.519\tools\OpenCover.Console.exe" -output:"%CD%\testcover.xml" -register:user -target:"C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\CommonExtensions\Microsoft\TestWindow\vstest.console.exe" -targetargs:"%CD%\bin\Debug\NunitTest.dll"
MSBuild.SonarQube.Runner.exe end
运行以上命令根据可能会出现以下问题:
问题1 命令找不到
可能会有童鞋遇到MSBuild.SonarQube.Runner.exe
is not recognized as an internal or external command,operable program or batch file.
当然可能有些童鞋不会遇到这个问题,这主要取决于环境变量path的设置
可以看到这个界面有两个地方可以设置path,上面是用户级别的,下面是系统级别的,如果你是在上面用户级别设置的path,则Jenkins无法读取到(这里仅仅是指默认情况下)当前用户变量的,因为Jenkins执行用户和当前用户并不是同一个用户.(大家可以在jenkins里执行whoami来看下jenkins里的执行用户).这里有两个解决办法:第一种办法就是指定可执行文件
MSBuild.SonarQube.Runner.exe
的完整路径(其它可执行文件也一样),第二,把环境变量添加到全局配置里.加到全局变量里虽然方便了,但是全局变量的总长度是有限制的,如果配置的过多很容易超出限制,还有一点问题就是像mono在安装的时候全自动添加很多环境变量,如果用户装了mono,使用全局的msbuild编译有时候会造成编译的结果和指定完整路径的编译结果不一致,这一点请用户自己斟酌.
问题2 相对路径问题
以上代码中我们使用了%CD%
,我们前面的示例都是在工程目录下执行的,%CD%即为当前目录,而在Jenkins环境中,当前目录是Jenkins\workspace\项目名
,如果处理不当,会导致编译错误.
第二段msbuild.exe
也是一样问题,它必须在工程目录下的时候才不需要指定要编译的项目名,如果当前目录下没有sln或者csproj文件,则需要显式指定项项目文件的完整路径如msbuild.exe "E:\personalproject\newTest2018\ConsoleApp1\NunitTest\NunitTest.csproj"
问题3 路径是否需要加引号
这其实是一个常见的问题,我们会发现有时候路径不带引号不会出现问题,有时候会出现问题,就笔者的经验,如果路径中没有空格则不用加引号,如果有则需要加引号.因此为了避免不必要的麻烦,建议的最佳实践是路径都加上引号.
问题4 默认Jenkins账户无法编译Sonarqube项目
我们把所有的问题都解决完之后,会发现Jenkins仍然构建失败,提示信息如下Running the Scanner for MSBuild under Local System or Network Service account is not supported. Please, use a local or domain user account instead.
以上错误明确提出,Sonarqube MSbuild 扫描器不支持本地系统账户或者网络服务账户,需要使用普通账户登陆.下面我们讲一下如何处理这个问题.
我们打开windows cmd执行whoami查看一下当前用户:
右击我的电脑
选择管理
然后从管理界面里面找到服务
或者在cmd界面输入services.msc
来打开服务管理界面,从服务管理界面找到jenkins
服务,右键点击属性
,在弹出的对话框中切换到登陆
标签,如果没有登陆则是本地败,我们选择此账户
然后输入账户和密码点击确定.
完成以上操作以后重新启动jenkins服务然后再执行脚本,就可以编译通过了.
.net持续集成sonarqube篇之 sonarqube与jenkins集成(插件模式)
系列目录
Jenkins通过插件集成Sonarqube
通过上一节我们了解了如何配置以使jenkins ci环境中可以执行sonarqube构建,其实Sonarqube官方也提供了jenkins插件以便更方便的管理.使用插件来执行sonarqube项目有以下优点
1.可以很清楚的看到项目是Sonarqube项目,如下图示
Sonarqube的begin,end不需要手动写,而是自动选择,项目名称,项目版本一目了然.不需要查看cmd信息.有点流水线
的感觉.
2.更好地与Sonarqube集成,请看下图
我们可以看到使用Sonarqube插件的项目是这样的,能够在jenkins页面展示项目的状态和sonarqube服务端的处理状态,我们点击图中的与sonarqube相关的图标会自动进入Sonarqube web管理页面,并且自动定位到本项目,这样如果构建项目特别多的情况下给我们带来很多方便.
3.与Jenkins PipeLine集成
以上仅仅是方便之处,然而并没有显示出插件无可取代之处,它的无可取代之处在于使用jenkins PipeLine时必须使用此插件.
说了这么多,下面介绍如何安装配置sonarqube Jenkins插件.
进入Jenkins插件管理界面,切换到''available''界面,输入sonarQube Scanner
然后安装(关于jenkins插件安装前面章节有讲到,这里不再赘述).安装完成以后开始配置.
工具选项配置
进入Manage Jenkins>Global Tool Configuration
找到sonarqube for msbuild
配置如下
其中名称可以随便选择,只要方便管理即可.
再找到sonarqube scanner
,配置如下
配置完成后点击最下面的
save
保存
点击完保存之后,我们再进入config system
找到sonarqube servers
配置如下
serverurl要根据实际情况配置,如果sonarqube和jenkins并不在同一台机器,则需要配置ip地址.
下面我们新建一个自由式任务.名称为mysonar(名称随意) 进入到Build
栏目,点击Add Build Steps
,我们从来拉列表中选择Sonarqube开始标识(通过前面的章节我们了解到,sonarqube构建包括开始标记,结束标记,然后中间是msbuild构建)
点击后会出现以下配置项,按实际情况配置即可
指定项目名,key(key可以任意起名,只做为惟一标识,并不是ssh登陆类似的key)
然后再新建一个执行bat的步骤.如下图
这里很普通,指定一个要编译的项目,需要注意的是我这里有环境变量msbuild,如果找不到请添加环境变量或者指定msbuild完整路径.
然后再添加一个步骤,这次选择SonarScanner for msbuild -end analysis.
然后点击确定完成创建,我们点击build now
触发一次构建.
构建成功后信息如下图
我们点击红色框先的任意一项,就可以跳转到sonarqube web管理界面,如下图示
需要注意的是第一次运行并不能构建成功,这是因为Jenkins需要下载相关插件,插件下载成功后我们进入
Jenkins\tools\hudson.plugins.sonar.MsBuildSQRunnerInstallation
目录下的你的 SonarScanner for MSBuild
的名字,它就是你在Global Tool Configuration>SonarScanner for MSBuild
指定的名称,进去以后找到SonarQube.Analysis.xml
对它进行配置,关于此文件的配置前面我们讲到过,这里不再赘述.
Sonarqube插件集成单元测试覆盖报告
回忆前面章节,添加sonarqube单元测试覆盖率报告需要额外执行一步运行单元测试的代码,这并不是重点,重点在于如何在Begin Analysis
部分指定单元测试执行文件,这里通过指定Additional arguments
来实现,如下图示
然后再在msbuild构建完成后添加一步执行单元测试的代码(可以复制前面的代码)就行了,这里需要说明的是前面为了方便讲解我们是在项目目录下执行脚本,使用了%CD%
这样的相对路径,Jenkins中建议换成绝对路径,以防出现不必要的麻烦.
完了再进入Sonarqube web管理界面,就可以看到有单元测试覆盖率报告了
Token方式与Sonarqube server交互
上一节我们讲解了通过配置SonarQube.Analysis.xml
方式实现与Sonarqube server交互(实际上我们执行构建的时候sonarqube runner是通过http方式把数据提交到sonarqube server),这样做有非常明显的缺点.第一是安全问题,我们知道其实我们是把admin的用户名和密码写入了SonarQube.Analysis.xml
文件里,这样很容易暴露管理员账户,在企业生产环境中,如果有恶意的人获取了管理员账户,则可以进行任意构建,然后触发布,这样会造成非常严重的后果,即使被没有恶意的开发者获取到,开发者可能出于好奇心在生产环境中进行测试尝试,这样也可能会造成非常严重的后果.第二是管理很不方便,如果在生产环境的jenkins是分布式的,那么我们进入每一台服务器更改配置文件是很不方便的,如果管理员账户和密码更改了还要进入每台服务器更改,虽然现在有各种自动化的工具使得这种操作不是特别麻烦的问题,但是集中的配置更加方便维护.下面我们讲解如何通过在Jenkins中为Sonarqube server添加token
来解决以上两个问题.
在Sonarqube里生成token
首先需要说明的是,只有管理员账户可以生成token,其它账户不可进行此操作.我们进入sonarqube web管理界面,执行以下操作
进入我的账户后security
标签,可以看到如下界面
我们在红框内的文本框里输入key的名字,此时Generate按钮变为激活状态,我们点击一下就可以生成一个token
我们点击copy
或者直接复制把token存储到文本文档或者其它地方,需要注意的是token必须保存,退出这个页面后token的值就会消失(这里说的消失是指不再显示,而不是真正的消失
).
把生成的token添加到Jenkins里
我们再回到jenkins,进入Manage Jenkins>configure system
找到SonarQube servers
把token粘贴到Server authentication token
需要注意的时,如果已经在
SonarQube.Analysis.xml
配置了账号密码,则需要删除掉,即删除以下代码
<Property Name="sonar.login">admin</Property>
<Property Name="sonar.password">admin</Property>
原文出处:https://www.cnblogs.com/tylerzhou/p/11273847.html
.net持续集成sonarqube篇之 sonarqube触发webhook
系列目录
WebHook近些年来变得越来越流行,github,gitlab等代码托管平台都提供webhook功能.关于webhook这里不做详细介绍,大家可以参阅读相关互联网书籍或者材料来更深了解.可以把它简单理解为某一事件完成以后的一个回调.
在持续集成环境里,我们可以使用Sonarqube的webhook功能来实现持续发布和发布包归档功能.大致思路是当项目构建成功后我们可以通过webhook通知服务器构建任务已完成,接下来web 服务器可以根据webhook传递的参数决定要处理的包是哪个项目的包(通过项目的key来判断),如何对包进行归档以及如何把包发布到远程服务器(通过http,ftp等方式).
Web服务器搭建
要想实现webhook,必须有一个预先设计好的web服务器供回调.我们预先建好了一个web项目(新建一个mvc项目即可)
由于是测试,我们这里就用Visual的模板生成一个mvc项目,然后在Home控制器下新建一个Action,代码如下:
public IActionResult HookTest([FromBody]SonarQubeVm sonar)
{
return new EmptyResult();
}
由于Sonarqube webhook是通过post方式提交,因此action必须支持Post方式请求.
参数sonar是SonarQubeVm
类型的参数,是根据Sonarqube请求规格文档构建的,代码如下:
public class SonarQubeVm
{
public DateTime? AnalysedAt { get; set; }
public SonarProjectInfo project { get; set; }
public string ServerUrl { get; set; }
public string Status { get; set; }
public string TaskId { get; set; }
}
public class SonarProjectInfo
{
public string Key { get; set; }
public string Name { get; set; }
}
注意以上参数并不完全包含Sonarqube返回的所有参数,我们只取了部分.关于Sonarqube webhook完整请求参数请查看
http://localhost:9000/documentation/webhooks
,localhost:9000是默认的服务器的端口号,如果你更改了端口号或者从外网请求,则要更改为实际的ip地址(或者域名)加上指定的端口号.
WebHook调用
在Sonarqube里可以通过两种方式调用webhook,全局模式和项目模式.全局模式每当一个构建成功后就会触发.项目模式则只有指定的项目构建以后才会触发.
全局模式
如上图示,我们点击全局Administration
然后点击configuration在出现的下拉列表里选择WebHooks,此时右上角有一个create
按钮,点击后出现一个弹出框,要求输入名称和url,然后点击确定.
我们以调试模式启动web项目,然后执行一个Sonarqube项目构建,执行完成后看看是否有请求到达web服务器.
MSBuild.SonarQube.Runner.exe begin /k:"mytest" /n:"mytest" /v:"v3.0" /d:sonar.cs.opencover.reportsPaths="%CD%\testcover.xml"
msbuild.exe
"E:\personalproject\newTest2018\ConsoleApp1\packages\OpenCover.4.6.519\tools\OpenCover.Console.exe" -output:"%CD%\testcover.xml" -register:user -target:"C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\CommonExtensions\Microsoft\TestWindow\vstest.console.exe" -targetargs:"%CD%\bin\Debug\NunitTest.dll"
MSBuild.SonarQube.Runner.exe end
以上是我们上一节讲单元测试的时候执行的代码只修改了版本号.我们执行它.
等等以上代码都执行完成,稍等片刻我们就可以看到http请求击中断点
通过serverurl是来自localhost:9000,我们可以确定是Sonarqube发来的请求.项目的key和name都是我们设定的mytest
以上仅是个示例程序,没有有用代码,实际项目中我们可以根据webhook请求的key来获取到构建的是哪个项目,然后根据预先设定的逻辑决定把它归档到哪里,以及把它发布到哪些web服务器下的哪些目录里(前面我们讲过通过ftt方式发布web项目,可以在这里使用)
项目模式
项目模式与全局模式设置完全一样,只是入口不同,项目模式需要进入项目的Administration
标签里进行设置.仍然以mytest项目为例子,我们打开mytest项目,进入到Administration标签里选择webhooks即可.
设置和全局设置一样,这里不再赘述.
请求认证
通过以上配置,我们成功搞好了webhook功能,然而以上代码根本无法使用到生产环境中,因为没有对请求进行认证,如果任何人都可以调用构建服务器地址则后果不堪设想.我们必须对请求进行认证,然后再决定是否执行相应逻辑.
由于sonaqube不支持设置header,因此我们无法使用复杂的请求认证.只能使用基本的http认证
我们在服务端增加以下类
public class BasicAuthenticationAttribute: ActionFilterAttribute
{
protected string Username { get; set; } = "sto";
protected string Password { get; set; } = "sto";
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var req = filterContext.HttpContext.Request;
var auth = req.Headers["Authorization"].ToString();
if (!String.IsNullOrEmpty(auth))
{
var cred = System.Text.Encoding.ASCII.GetString(Convert.FromBase64String(auth.Substring(6))).Split('':'');
var user = new { Name = cred[0], Pass = cred[1] };
if (user.Name == Username && user.Pass == Password) return;
}
filterContext.Result = new UnauthorizedResult();
}
}
以上代码中,我们通过硬编码方式指定了用户名和密码,实际生产环境中我们可以通过查询数据库来获取用户名和密码. 在OnActionExecuting
重写方法中我们通过头信息Authorization
获取加密的Base64字符串,然后通过:
分割获取到用户名和密码.然后和真实用户名密码做对比然后决定下一步动作.
我们把这个filter加到请求方法上.
改造后的代码如下:
[BasicAuthentication]
public IActionResult HookTest([FromBody]SonarQubeVm sonar)
{
return new EmptyResult();
}
我们把webhook的url更新为如下:
http://sto:sto1@localhost:49442/home/HookTest
实际上服务端逻辑要求账户和密码都必须是sto能请求,我们故意把密码改为sto1看看请求是否能成功.
我们仍然执行前面的构建代码,只是把版本号增加一下.
我们再进入webhook管理界面,可以看到请求失败了
我们点击失日期后面的四框
图标,可以看到失败的状态是401
我们把请求地址更改为如下
http://sto:sto@localhost:49442/home/HookTest
这里sto1改为服务器期待的sto,请求就能成功了.
原文出处:https://www.cnblogs.com/tylerzhou/p/11261868.html
.net持续集成sonarqube篇之 sonarqube集成单元测试
系列目录
通过前面章节我们可以看到,不论怎么构建,单元测试覆盖率一栏总是0%
这是因为单元测试覆盖率报告需要额外集成.这一节我们就讲解如何在sonarqube里集成单元测试覆盖率报告.
这里需要借助Opencover来生成单元测试覆盖报告文档,Opencover前面章节我们介绍过,不了解的朋友可以查看一下前面相关部分的章节.
我在本地有一个包含单元测试项目(大家可以自己建一个包含单元测试的项目,关于单元测试前面章节也有详细讲解,这里不再赘述).进入包含项目sln或者csproj的文件,执行以下命令.
MSBuild.SonarQube.Runner.exe begin /k:"mytest" /n:"mytest" /v:"v1.0" /d:sonar.cs.opencover.reportsPaths="%CD%\testcover.xml"
msbuild.exe
"E:\personalproject\newTest2018\ConsoleApp1\packages\OpenCover.4.6.519\tools\OpenCover.Console.exe" -output:"%CD%\testcover.xml" -register:user -target:"C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\CommonExtensions\Microsoft\TestWindow\vstest.console.exe" -targetargs:"%CD%\bin\Debug\NunitTest.dll"
MSBuild.SonarQube.Runner.exe end
Begin 和end是固定格式,这里begin部分多了一个/d选项,/d为dynamic properties 动态属性.通过动态属性指定单元测试报告的位置.%CD%
即为当前目录
第二段 msbuild.exe执行构建. 第三段 这里是生成单元测试覆盖率报告的关键. 首先指定Opencover所在位置,-register user 为注册当前windows用户以使其有权限执行.-output 指定覆盖率文件输出位置,这里必须和上面的 sonar.cs.opencover.reportsPaths保持一致
. -target为要指定的单元测试runner,这里使用的是visual studio自带的vstest.console.exe targetargs指定要进行单元测试的目标dll.
执行完成以后,我们再打开sonarqube web管理界面就会看到刚刚生成的mytest项目
通过上图我们可以看到mytest项目的单元测试覆盖率为56.7%
我们进入mytest这个项目,然后点击单元测试覆盖率数字下面的链接
点击后进入以下页面:
通过这个界面,我们可以看到每一个类的的单元测试覆盖率和未覆盖的行数.我们点击类名,便可以进入具体的类.
这个图中,蓝杠部分为单元测试覆盖到的代码,红框部分则为未覆盖到的代码.
代码大视窗显示.
对于管理员来说,可能仅仅需要大致浏览一下代码,然后告知具体开发者需要修改.对于开发者来说,可能需要详细查看代码.以上截图只截了主视窗,实际上左侧还有固定的导航栏.这样对于查看代码可能不是很友好,详细查看代码的时候我们可能想在更大的视窗里查看.这时候我们可以点击右上角的"四杠图标"
选择open in new window便可以在新窗口中打开代码.此时整个区域都是代码,无关的内容都没了
以上代码虽然在一个单独的视窗里显示,但是仍然有蓝杠和红杠标识,有些童鞋可能感觉不是很舒服,想要看到清洁代码,此时点击
四框图标
选择Show raw source
即可显示原始代码.
原文出处:https://www.cnblogs.com/tylerzhou/p/11253855.html
今天关于Maven SonarQube多模块和maven sonar插件的介绍到此结束,谢谢您的阅读,有关.net持续集成sonarqube篇之 sonarqube与jenkins集成(命令模式)、.net持续集成sonarqube篇之 sonarqube与jenkins集成(插件模式)、.net持续集成sonarqube篇之 sonarqube触发webhook、.net持续集成sonarqube篇之 sonarqube集成单元测试等更多相关知识的信息可以在本站进行查询。
以上就是给各位分享什么是“ X-Content-Type-Options = nosniff”?,其中也会对什么是suv汽车进行解释,同时本文还将给你拓展.jdbc4.MySQLNonTransientConnectionException: No operations allowed after connection closed.、.NET Core 中 WebOperationContext.Current.OutgoingResponse.ContentType 的替代方法是什么、.Net Core 配置文件读取IOptions,IOptionsMonitor,IOptionsSnapshot、aiohttp.client_exceptions.ContentTypeError: 0:json(content_type=‘??‘)等相关知识,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!
本文目录一览:- 什么是“ X-Content-Type-Options = nosniff”?(什么是suv汽车)
- .jdbc4.MySQLNonTransientConnectionException: No operations allowed after connection closed.
- .NET Core 中 WebOperationContext.Current.OutgoingResponse.ContentType 的替代方法是什么
- .Net Core 配置文件读取IOptions,IOptionsMonitor,IOptionsSnapshot
- aiohttp.client_exceptions.ContentTypeError: 0:json(content_type=‘??‘)
什么是“ X-Content-Type-Options = nosniff”?(什么是suv汽车)
我正在使用OWASP ZAP在我的本地主机上进行一些渗透测试,并且不断报告此消息:
Anti-MIME-Sniffing标头X-Content-Type-Options未设置为’nosniff’
此检查特定于Internet Explorer 8和Google Chrome。如果Content- Type标头未知,请确保每个页面都设置了Content-Type标头和X-CONTENT-TYPE-OPTIONS
我不知道这意味着什么,也无法在网上找到任何东西。我尝试添加:
<meta content="text/html; charset=UTF-8; X-Content-Type-Options=nosniff" http-equiv="Content-Type" />
但我仍然收到警报。
设置参数的正确方法是什么?
答案1
小编典典它阻止浏览器进行MIME类型的嗅探。现在,大多数浏览器都在使用此标头,包括Chrome / Chromium,Edge,IE> = 8.0,Firefox>= 50和Opera> =13。请参阅:
发送带有值nosniff的新X-Content-Type-Options响应标头将阻止Internet
Explorer进行MIME嗅探已声明的内容类型的响应。
编辑:
哦,那是HTTP标头,而不是HTML元标记选项。
.jdbc4.MySQLNonTransientConnectionException: No operations allowed after connection closed.
com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after connection closed.
at sun.reflect.GeneratedConstructorAccessor65.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
at com.mysql.jdbc.Util.getInstance(Util.java:386)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1015)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:989)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:975)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:920)
at com.mysql.jdbc.ConnectionImpl.throwConnectionClosedException(ConnectionImpl.java:1311)
at com.mysql.jdbc.ConnectionImpl.checkClosed(ConnectionImpl.java:1303)
at com.mysql.jdbc.ConnectionImpl.createStatement(ConnectionImpl.java:2683)
at com.mysql.jdbc.ConnectionImpl.createStatement(ConnectionImpl.java:2665)
at security.view.util.SqlUtils.insert(SqlUtils.java:315)
at security.view.util.SqlUtils.processKill(SqlUtils.java:109)
at security.view.util.SqlUtils.sql(SqlUtils.java:148)
at security.view.util.SqlUtils.sqlJsonObj(SqlUtils.java:418)
at security.view.util.SqlUtils.processKill(SqlUtils.java:97)
at security.view.util.SqlUtils.sql(SqlUtils.java:148)
.NET Core 中 WebOperationContext.Current.OutgoingResponse.ContentType 的替代方法是什么
如何解决.NET Core 中 WebOperationContext.Current.OutgoingResponse.ContentType 的替代方法是什么?
.NET Core 中以下代码片段的替代方法是什么?
WebOperationContext webContext = WebOperationContext.Current;
webContext.OutgoingResponse.ContentType = "text/html";
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)
.Net Core 配置文件读取IOptions,IOptionsMonitor,IOptionsSnapshot
前言
众所周知,appsetting.json 配置文件是.Net 的重大革新之心,抛开了以前繁杂的xml文件,使用了更简洁易懂的json方式,简直不要太舒服了!东西虽然好,但怎么在程序中读取这个配置呢,是每个新手必须要跨过去的坑(当然也是包括我这个菜狗子)。
遇事不明上注入,只要是遇到不知道怎么办的事,首先要往注入方便想,框架有了这个配置文件,必然配备了简单直接的读取API,按照我的习惯,直接上代码:
首先,我们在配置文件中,增加 Demo 配置节点:
{ "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, "Demo": { "Value1": "1", "Value2": "2", "Value3": "3", "Value4": "4" } }
在需要用到配置文件的地方,注入 IConfiguration 服务接口
private readonly IConfiguration _configuration; public ValuesController(IConfiguration configuration) { _configuration = configuration; }
通常,我们比较直接的方式是通过 GetSection 获取对应的配置节点,然后再获取对应的配置项
var section = _configuration.GetSection("Demo"); var value1 = section.GetValue("Value1", "1");
如果 Demo 节点内还有更深的节点,GetSection 可以通过 : 深入到对应的下一个节点
appsetting.json
{ "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, "Demo": { "Value1": "1", "Value2": "2", "Value3": "3", "Value4": "4", "Model" { "Name": "小二", "Phone": "12345678911" } } }
var model = _configuration.GetSection("Demo:Model");
有些小伙伴可能就会问了,那我每个需要用到的地方都需要直接以字符串作为参数去读取配置,以后要是突然改了配置项,岂不是非常麻烦;
这点小伙伴们大可放心,你可以定义一个实体类,然后绑定上去,以后有什么更改了,直接重命名对应的属性就行了,实例代码
方法一:
var options = new DemoOptions(); _configuration.GetSection("Demo").Bind(options);
方法二:
var options2 = _configuration.GetSection("Demo").Get<DemoOptions>();
方法三:在 Startup.cs、.Net 6 以上在 Program.cs- 中使用依赖注入方式,以下是 .Net 6
builder.Services.Configure<DemoOptions>(builder.Configuration.GetSection("Demo"));
在需要使用的地方注入 IOptions<TOptions> 即可获取到配置值,需要注意的是,IOptions 是单例(Singleton)服务,即在应用启动时进行注册,后续更改配置文件,该 IOptions 将不会同步更新,依然还是旧值
private readonly DemoOptions _demoOptions; public ValuesController(IOptions<DemoOptions> options) { _demoOptions = options.Value; }
如需要配置进行热更新,只需要改成注入 IOptionsMonitor<TOptions> 或者 IOptionsSnapshot<TOptions>;IOptionsSnapshot<TOptions>的生命周期是作用域(Scoped),每次请求都会重新获取一次配置;IOptionsSnapshot<TOptions> 的生命周期是单例(Singleton),与 IOptions<TOptions> 不一样的是当配置文件发生改变时,将会自动同步响应。
到此这篇关于.Net Core 配置文件读取IOptions,IOptionsMonitor,IOptionsSnapshot的文章就介绍到这了,更多相关.Net Core 文件读取内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!
- .NetCore获取Json和Xml格式的配置信息
- .NET Core控制台应用ConsoleApp读取appsettings.json配置文件
- .net6 使用Senparc开发小程序配置过程
- .NET Core自定义配置文件
- .NET Core读取配置文件
- .NET 中配置从xml转向json方法示例详解
aiohttp.client_exceptions.ContentTypeError: 0:json(content_type=‘??‘)
aiohttp.client_exceptions
- 问题
- 解决
问题
# 获取异步requests
async with aiohttp.ClientSession() as session:
async with session.post(url, headers=headers, data=data) as resp:
# 写入数据
csvWriter.writerow(await resp.json()) # 读取内容是异步的,需要挂起
print('库编号', data['p'], '爬取完毕!')
from aioHTTP_Requests import requests
async def req(URL):
headers = {"Accept": 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
"Accept-Language": "zh-CN,zh;q=0.9", "Host": "xin.baidu.com",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/72.0.3626.121 Safari/537.36", }
resp = await requests.get(URL,headers=headers,timeout=10,verify_ssl=False)
resp_text = await resp.json(encoding='utf-8')
return resp_text
if __name__ == "__main__":
print("HELLO WORLD")
URL = "https://xin.baidu.com/detail/basicAjax?pid=xlTM-TogKuTw9PzC-u6VwZxUBuZ5J7WMewmd"
loop = asyncio.get_event_loop()
loop.run_until_complete(req(URL))
csvWriter.writerow(await resp.json())
运行上面的程序会报错
解决
ContentTypeError:类型错误
在resp.json()
:传入编码文本类型参数即可:
resp.json(content_type='text/html',encoding='utf-8')
参考:Link
衷心感谢!
关于什么是“ X-Content-Type-Options = nosniff”?和什么是suv汽车的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于.jdbc4.MySQLNonTransientConnectionException: No operations allowed after connection closed.、.NET Core 中 WebOperationContext.Current.OutgoingResponse.ContentType 的替代方法是什么、.Net Core 配置文件读取IOptions,IOptionsMonitor,IOptionsSnapshot、aiohttp.client_exceptions.ContentTypeError: 0:json(content_type=‘??‘)等相关知识的信息别忘了在本站进行查找喔。
本文标签: