-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcodenote
More file actions
837 lines (647 loc) · 43.3 KB
/
codenote
File metadata and controls
837 lines (647 loc) · 43.3 KB
1
2
3
4
5
6
7
8
9
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
int firstArg;
if (args.length > 0) {
try {
firstArg = Integer.parseInt(args[0]);
} catch (NumberFormatException e) {
System.err.println("Argument" + args[0] + " must be an integer.");
System.exit(1);
}
}
#DI IoC
http://www.vogella.com/tutorials/DependencyInjection/article.html
Dependency injection is a concept valid for any programming language. The general concept behind dependency injection is called Inversion of Control. According to this concept a class should not configure its dependencies statically but should be configured from the outside.
A Java class has a dependency on another class, if it uses an instance of this class. We call this a _class dependency. For example, a class which accesses a logger service has a dependency on this service class.
Ideally Java classes should be as independent as possible from other Java classes. This increases the possibility of reusing these classes and to be able to test them independently from other classes.
If the Java class creates an instance of another class via the new operator, it cannot be used (and tested) independently from this class and this is called a hard dependency. The following example shows a class which has no hard dependencies.
package com.example.e4.rcp.todo.parts;
import java.util.logging.Logger;
public class MyClass {
private final static Logger logger;
public MyClass(Logger logger) {
this.logger = logger;
// write an info log message
logger.info("This is a log message.")
}
}
#Please note that this class is just a normal Java class, there is nothing special about it, except that it avoids direct object creation.
A framework class, usually called the dependency container, could analyze the dependencies of this class. With this analysis it is able to create an instance of the class and inject the objects into the defined dependencies, via Java reflection.
This way the Java class has no hard dependencies, which means it does not rely on an instance of a certain class. This allows you to testyour class in isolation, for example by using mock objects.
Mock objects (mocks) are objects which behave similar as the real object. But these mocks are not programmed; they are configured to behave in a certain predefined way. Mock is an English word which means to mimic or to imitate.
If dependency injection is used, a Java class can be tested in isolation.
1.2. Using annotations to describe class dependencies
Different approaches exist to describe the dependencies of a class. The most common approach is to use Java annotations to describe the dependencies directly in the class.
The standard Java annotations for describing the dependencies of a class are defined in the Java Specification Request 330 (JSR330). This specification describes the @Inject and @Named annotations.
The following listing shows a class which uses annotations to describe its dependencies.
// import statements left out
public class MyPart {
@Inject private Logger logger;
// inject class for database access
@Inject private DatabaseAccessClass dao;
@Inject
public void createControls(Composite parent) {
logger.info("UI will start to build");
Label label = new Label(parent, SWT.NONE);
label.setText("Eclipse 4");
Text text = new Text(parent, SWT.NONE);
text.setText(dao.getNumber());
}
}
#Please note that this class uses the new operator for the user interface components. This implies that this part of the code is nothing you plan to replace via your tests. In this case you made the decision to have a hard coupling to the corresponding user interface toolkit.
1.3. Where can objects be injected into a class according to JSR330?
Dependency injection can be performed on:
the constructor of the class (construction injection)
a field (field injection)
the parameters of a method (method injection)
It is possible to use dependency injection on static and on non-static fields and methods. Avoiding dependency injection on static fields and methods is a good practice, as it has the following restrictions and can be hard to debug.
Static fields will be injected after the first object of the class was created via DI, which means no access to the static field in the constructor
Static fields can not be marked as final, otherwise the compiler or the application complains at runtime about them
Static methods are called only once after the first instance of the class was created
1.4. Order in which dependency injection is performed on a class
According to JSR330 the injection is done in the following order:
constructor injection
field injection
method injection
The order in which the methods or fields annotated with @Inject are called is not defined by JSR330. You cannot assume that the methods or fields are called in the order of their declaration in the class.
As fields and method parameters are injected after the constructor is called, you cannot use injected member variables in the constructor.
2. Java and dependency injection frameworks
You can use dependency injection without any additional framework by providing classes with sufficient constructors or getter and setter methods.
A dependency injection framework simplifies the initialization of the classes with the correct objects.
Two popular dependency injection frameworks are Spring and Google Guice.
The usage of the Spring framework for dependency injection is described in Dependency Injection with the Spring Framework - Tutorial.
#Dependency Injection, Annotations, and why Java is Better Than you Think it is
https://www.objc.io/issues/11-android/dependency-injection-in-java/
My beef was not original or well thought out, but here are my issues, roughly:
It’s verbose. There’s no shortened syntax for implementing callbacks, like blocks or lambdas, so you have to write a lot of boilerplate to implement even a simple interface. If you need an object that holds four things, you have to create a class with four named fields.
It’s rigid. Writing sensible Java constantly requires you to specify exactly which exception you’re catching, to specify which type you’re taking in, to check and make sure that your references aren’t null, and to import every class you need to use. And while there is some flexibility at runtime, it’s nowhere close to what you get in the Objective-C runtime, much less something like Ruby or Python.
That was essentially my view of Java. It was this kind of Java:
public class NumberStack {
List<Integer> mNumbers = new ArrayList<Integer>();
public void pushNumber(int number) {
mNumbers.add(number);
}
public Integer popNumber() {
if (mNumber.size() == 0) {
return null;
} else {
return mNumber.remove(mNumber.size() - 1);
}
}
}
Add some inner classes and interfaces to the mix, and that is what I learned and worked with. Not the worst thing in the world to be writing, but other languages had features and flexibility that I wished that I had in Java. Never did I find myself writing code in another language and saying, “Man, I wish this were more like Java.”
My opinion has changed.
Something Peculiar to Java
Oddly enough, the tool that changed my mind is only popular because of problems that are peculiar to Java. Consider the following code:
public class Payroll {
...
public long getWithholding(long payInDollars) {
...
return withholding;
}
public long getAfterTaxPay(Employee employee) {
long basePay = EmployeeDatabase.getInstance()
.getBasePay(employee);
long withholding = getWithholding(basePay);
return basePay - withholding;
}
}
This class has a dependency in getAfterTaxPay() called EmployeeDatabase. There are a variety of ways that we could create this object, but in this example, I’ve used a typical singleton pattern of having a static getInstance method.
Dependencies in Java are surprisingly strict things. Whenever I write a line of code like this:
long basePay = EmployeeDatabase.getInstance().getBasePay(employee);
I create a strict dependency on the EmployeeDatabase class. Not only that, but I also create a strict dependency on a particular method in EmployeeDatabase: the getInstance() method. In other languages, I might be able to swizzle or monkey patch this kind of thing. Not that that’s a great idea, necessarily, but it is at least possible. Not so in Java.
Other ways of creating a dependency are even more strict than that. Let’s say that instead, I wrote that line like this:
long basePay = new EmployeeDatabase().getBasePay(employee);
When I use the new keyword, I tie myself down in all the same ways I did with the static method, but I also add one more: calling new EmployeeDatabase() must always yield an instance of the EmployeeDatabase class. You can’t rewrite that constructor to return a mock subclass, no matter what you do.
Dependency Injection
The way we usually solve this problem is to use a technique called dependency injection. It’s not a technique unique to Java, but because of the aforementioned issues, Java is in particularly dire need of it.
Dependency injection simply means receiving collaborators as constructor parameters instead of fetching them ourselves. So Payroll would look like this instead:
public class Payroll {
...
EmployeeDatabase mEmployeeDatabase;
public Payroll(EmployeeDatabase employeeDatabase) {
mEmployeeDatabase = employeeDatabase;
}
public long getWithholding(long payInDollars) {
...
return withholding;
}
public long getAfterTaxPay(Employee employee) {
long basePay = mEmployeeDatabase.getBasePay(employee);
long withholding = getWithholding(basePay);
return basePay - withholding;
}
}
Is EmployeeDatabase a singleton? A mocked-out subclass? A context-specific implementation? Payroll no longer needs to know.
Declarative Dependency Programming
All of that is just background for what I really want to talk about: dependency injectors.
(An aside: I know it’s a little odd to be two problems deep before actually discussing something nifty, but I hope you’ll bear with me. Understanding what Java gets right just requires more work than it does with other languages. It’s the nature of the beast.)
See, now that we are passing in dependencies through our constructors, our objects are more difficult to use and more difficult to change. Before I used dependency injection, I could use Payroll like this:
new Payroll().getAfterTaxPay(employee);
Now, though, I have to write this:
new Payroll(EmployeeDatabase.getInstance()).getAfterTaxPay(employee);
Plus, anytime I change Payroll’s dependencies, I have to change every place I write new Payroll, too.
A dependency injector allows me to forget about writing code to explicitly supply dependencies. Instead, I declaratively say what my dependencies are, and the tool worries about supplying them when they’re needed. There are a variety of dependency injection tools out there; for these examples, I’ll be using RoboGuice.
To do this, we use Java’s tool for describing code: the annotation. We declare our dependencies by simply annotating our constructor:
@Inject
public Payroll(EmployeeDatabase employeeDatabase) {
mEmployeeDatabase = employeeDatabase;
}
The @Inject annotation says, “To build an instance of Payroll, execute this constructor, passing in values for all of its parameters.” Then when I actually need a Payroll instance, I ask the dependency injector to build me one, like so:
Payroll payroll = RoboGuice.getInjector(getContext()).getInstance(Payroll.class);
long afterTaxPay = payroll.getAfterTaxPay(employee);
Once I’m constructing instances in this way, I can use the injector itself to configure how dependencies are satisfied. Do I want EmployeeDatabase to be a singleton? Do I want to use a customized subclass? All of this can be specified in one place.
The Wider World of Declarative Java
It’s an easily described tool, but it’s hard to overestimate how fundamental the gap is between Java with and without a dependency injector. Without a dependency injector, aggressive refactoring and test-driven development are laborious. With one, they are effortless. The only thing more indispensable to a Java developer than a dependency injector is a good IDE.
Still, it’s just the first taste of a wider set of possibilities. Most of the exciting new stuff for Android developers originating outside Google revolves around annotation-based APIs.
Take ButterKnife, for example. We spend a lot of time in Android wiring up listeners to view objects, like this:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_content);
View okButton = findViewById(R.id.ok_button);
okButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
onOkButtonClicked();
}
});
}
public void onOkButtonClicked() {
// handle button click
}
ButterKnife allows us to instead provide a little bit of metadata that says, “Call onOkButtonClicked when the view with the id R.id.ok_button is clicked.” Like this:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_content);
ButterKnife.inject(this);
}
@OnClick(R.id.ok_button);
public void onOkButtonClicked() {
// handle button click
}
I could go on and on with more examples. There are libraries that use annotations to serialize and deserialize JSON, to stash fields in savedInstanceState, to generate code to interface with RESTful web services, and on and on and on.
Compile Time vs. Runtime Annotation Processing
While some tools may achieve similar effects with annotations, Java allows them to achieve these effects in different ways. Take RoboGuice and Dagger, for example. Both are dependency injectors; both use the @Inject annotation. But where RoboGuice reads your code annotations at runtime, Dagger reads them at compile time and generates code.
This has a few important benefits. It means that errors in your annotation semantics can be detected early. Dagger can tell you at compile time when you have a circular dependency; RoboGuice cannot.
It can also improve performance. Generated code can reduce startup time and eliminate the need to read annotations at runtime. Reading annotations requires the use of Java’s reflection APIs, which can be expensive on some Android devices.
An Example of Runtime Annotation Processing
I’d like to finish up by showing a simple example of how one might define and process a runtime annotation. Let’s say that you were an exceptionally impatient person and were tired of typing out fully qualified static constants in your Android codebase, constants like these:
public class CrimeActivity {
public static final String ACTION_VIEW_CRIME = “com.bignerdranch.android.criminalintent.CrimeActivity.ACTION_VIEW_CRIME”;
}
You could use a runtime annotation to do this work for you. First, you’d create the annotation class:
@Retention(RetentionPolicy.RUNTIME)
@Target( { ElementType.FIELD })
public @interface ServiceConstant { }
This code declares an annotation named ServiceConstant. The code is itself annotated with two annotations: @Retention, and @Target. @Retention says how long the annotation will stick around. Here, we say that we want to see it at runtime. If we wanted this annotation to be processed at compile time only, we could have specified RetentionPolicy.SOURCE.
The other annotation, @Target, says where you can put the annotation in your source code. Any number of values can be provided. Our annotation is only valid for fields, so we have just provided ElementType.FIELD.
Once the annotation is defined, we write some code to look for it and populate the annotated field automatically:
public static void populateConstants(Class<?> klass) {
String packageName = klass.getPackage().getName();
for (Field field : klass.getDeclaredFields()) {
if (Modifier.isStatic(field.getModifiers()) &&
field.isAnnotationPresent(ServiceConstant.class)) {
String value = packageName + "." + field.getName();
try {
field.set(null, value);
Log.i(TAG, "Setup service constant: " + value + "");
} catch (IllegalAccessException iae) {
Log.e(TAG, "Unable to setup constant for field " + field.getName() + " in class " + klass.getName());
}
}
}
}
Finally, we add the annotation to our code, and call our magic method:
public class CrimeActivity {
@ServiceConstant
public static final String ACTION_VIEW_CRIME;
static {
ServiceUtils.populateConstants(CrimeActivity.class);
}
}
Conclusion:
Well, that’s all I’ve got. So much for annotations in Java. I can’t say that I’m sure that all this has made you feel the same way as I do about Java, but I hope that you’ve seen some interesting stuff. While day-to-day Java may be lacking a bit in expressivity, there are a few basic building blocks in the Java kit that make it possible for advanced developers to create powerful tools that amplify the productivity of the entire community.
If you’re interested in diving in deeper, you will find the topic of driving code generation with annotations very interesting. It’s not necessarily pretty to read or write, but folks are doing some nifty work out there with the tools as they are. The source for ButterKnife is reasonably simple, if you’re interested in an example of how it’s done in the real world.
java.lang.Object
extended by java.text.Format
extended by java.text.DateFormat
extended by java.text.SimpleDateFormat
Date and Time Pattern Result
"yyyy.MM.dd G 'at' HH:mm:ss z" 2001.07.04 AD at 12:08:56 PDT
"EEE, MMM d, ''yy" Wed, Jul 4, '01
"h:mm a" 12:08 PM
"hh 'o''clock' a, zzzz" 12 o'clock PM, Pacific Daylight Time
"K:mm a, z" 0:08 PM, PDT
"yyyyy.MMMMM.dd GGG hh:mm aaa" 02001.July.04 AD 12:08 PM
"EEE, d MMM yyyy HH:mm:ss Z" Wed, 4 Jul 2001 12:08:56 -0700
"yyMMddHHmmssZ" 010704120856-0700
"yyyy-MM-dd'T'HH:mm:ss.SSSZ" 2001-07-04T12:08:56.235-0700
#Java Print string literal unicode as the actual character
for (int i=0x2500;i<=0x257F;i++) {
System.out.printf("0x%x : %c\n",i,(char)i);
}
for(int index=0;index<65536; index++)
System.out.prinln((char)index);
But you can not view the unicode chars above 256. They will be displayed as question mark.
Instead you write all unicode characters in a file using UTF8 format.
#Convert International String to \u Codes in java
http://stackoverflow.com/questions/6230190/convert-international-string-to-u-codes-in-java
#Printing out unicode from Java code issue in windows console
http://stackoverflow.com/questions/20386335/printing-out-unicode-from-java-code-issue-in-windows-console
In additions to the steps you have taken, you also need a PrintStream/PrintWriter that encodes the printed characters to UTF-8.
Unfortunately, Java designers have chosen to open the standard streams with the so called "default" encoding, which is almost always unusable*) under Windows. Hence, using System.out and System.err naively will make your program output appear differently, depending on where you run it. This is straight against the goal: compile once, run anywhere.
*) It will be some non standard "code page" nobody except Microsoft recognizes on this planet. And AFAIK, if for example you have a German keyboard and a "German" OEM Windows and you want to have date and time in your home time zone, there is just no way to say: But I want UTF-8 input/output in my CMD window. This is one reason why I have my dual Ubuntu booted most of the time, where it goes without saying that the terminal does UTF-8.
The following usually works for me in JDK7:
public static PrintWriter stdout = new PrintWriter(
new OutputStreamWriter(System.out, StandardCharsets.UTF_8), true);
For ancient Java versions, I replace StandardCharsets.UTF_8 by Charset.forName("UTF-8").
#Chinese Characters Displayed as Questions Marks in Mac Terminal
http://stackoverflow.com/questions/15488628/chinese-characters-displayed-as-questions-marks-in-mac-terminal/15516722#15516722
System.out printstream isn't created as a UTF-8 print stream. You can convert it to be one like this:
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
public class JavaTest {
public static void main(String[] args) {
try{
PrintStream out = new PrintStream(System.out, true, "UTF-8");
out.println("Hello");
out.println("施华洛世奇");
out.println("World");
}
catch(UnsupportedEncodingException UEE){
//...
}
}
}
You can also set the default encoding as per here by:
java -Dfile.encoding=UTF-8 -jar JavaTest.jar
#Gnu Make Makefile Examples
http://www.jwrr.com/content/Gnu-Makefile-Examples/
#Using make and writing Makefiles
https://www.cs.swarthmore.edu/~newhall/unixhelp/howto_makefiles.html
:read !"date +'%Y-%m-%d %H:%M:%S.%N %:::z'"
:read !date +'%Y-%m-%d %H:%M:%S.%N %:::z'
:read `date +'%Y-%m-%d %H:%M:%S.%N %:::z`
#Java String encoding conversion UTF-8 to SHIFT-JIS
stringToEncode.getBytes(Charset.forName("SHIFT-JIS"))
or
new String(unecodedString.getBytes("SHIFT-JIS"), "UTF-8")
Very strange,as:
byte[] b = resultString.getBytes("Shift_JIS");
String value = new String(b, "UTF-8");
didn't work, but:
String value = new String(resultString.getBytes("SHIFT-JIS"), "UTF-8")
Works like a charm. Maybe it was because of the underscore and lower case character in "Shift_JIS".
#jar
jar cf jar-file input-file(s)
As an example, suppose you wanted to put audio files and gif images used by the TicTacToe demo into a JAR file, and that you wanted all the files to be on the top level, with no directory hierarchy. You could accomplish that by issuing this command from the parent directory of the images and audio directories:
jar cf ImageAudio.jar -C images . -C audio .
The -C images part of this command directs the Jar tool to go to the images directory, and the . following -C images directs the Jar tool to archive all the contents of that directory. The -C audio . part of the command then does the same with the audio directory.
http://www.brendangregg.com/blog/2016-08-09/gdb-example-ncurses.html
https://cristos.vipserv.org/2015/03/a-crash-course-in-gnu-debugger-a-gdb-tutorial/
How to change the value of a local or global variable in gdb?
Acceptance Test Driven Development (ATDD)
Test Driven Development (TDD)
Behavior Driven Develpment (BDD)
#Java String UTF-8 SHIFT-JIS
http://stackoverflow.com/questions/37155417/string-encoding-conversion-utf-8-to-shift-jis/
http://www.journaldev.com/2394/java-dependency-injection-design-pattern-example-tutorial
Java Dependency Injection – DI Design Pattern Example Tutorial
Java Dependency Injection design pattern allows us to remove the hard-coded dependencies and make our application loosely coupled, extendable and maintainable. We can implement dependency injection in java to move the dependency resolution from compile-time to runtime.
Java Dependency injection seems hard to grasp with theory, so I would take a simple example and then we will see how to use dependency injection pattern to achieve loose coupling and extendability in the application.
Let’s say we have an application where we consume EmailService to send emails. Normally we would implement this like below.
package com.journaldev.java.legacy;
public class EmailService {
public void sendEmail(String message, String receiver){
//logic to send email
System.out.println("Email sent to "+receiver+ " with Message="+message);
}
}
EmailService class holds the logic to send email message to the recipient email address. Our application code will be like below.
package com.journaldev.java.legacy;
public class MyApplication {
private EmailService email = new EmailService();
public void processMessages(String msg, String rec){
//do some msg validation, manipulation logic etc
this.email.sendEmail(msg, rec);
}
}
Our client code that will use MyApplication class to send email messages will be like below.
package com.journaldev.java.legacy;
public class MyLegacyTest {
public static void main(String[] args) {
MyApplication app = new MyApplication();
app.processMessages("Hi Pankaj", "pankaj@abc.com");
}
}
At first look, there seems nothing wrong with above implementation. But above code logic has certain limitations.
MyApplication class is responsible to initialize the email service and then use it. This leads to hard-coded dependency. If we want to switch to some other advanced email service in future, it will require code changes in MyApplication class. This makes our application hard to extend and if email service is used in multiple classes then that would be even more harder.
If we want to extend our application to provide additional messaging feature, such as SMS or Facebook message then we would need to write another application for that. This will involve code changes in application classes and in client classes too.
Testing the application will be very difficult since our application is directly creating the email service instance. There is no way we can mock these objects in our test classes.
One can argue that we can remove the email service instance creation from MyApplication class by having a constructor that requires email service as argument.
package com.journaldev.java.legacy;
public class MyApplication {
private EmailService email = null;
public MyApplication(EmailService svc){
this.email=svc;
}
public void processMessages(String msg, String rec){
//do some msg validation, manipulation logic etc
this.email.sendEmail(msg, rec);
}
But in this case, we are asking client applications or test classes to initializing the email service that is not a good design decision.
Now let’s see how we can apply java dependency injection pattern to solve all the problems with above implementation. Dependency Injection in java requires at least following:
Service components should be designed with base class or interface. It’s better to prefer interfaces or abstract classes that would define contract for the services.
Consumer classes should be written in terms of service interface.
Injector classes that will initialize the services and then the consumer classes.
Java Dependency Injection – Service Components
For our case, we can have MessageService that will declare the contract for service implementations.
package com.journaldev.java.dependencyinjection.service;
public interface MessageService {
void sendMessage(String msg, String rec);
}
Now let’s say we have Email and SMS services that implement above interfaces.
package com.journaldev.java.dependencyinjection.service;
public class EmailServiceImpl implements MessageService {
@Override
public void sendMessage(String msg, String rec) {
//logic to send email
System.out.println("Email sent to "+rec+ " with Message="+msg);
}
}
package com.journaldev.java.dependencyinjection.service;
public class SMSServiceImpl implements MessageService {
@Override
public void sendMessage(String msg, String rec) {
//logic to send SMS
System.out.println("SMS sent to "+rec+ " with Message="+msg);
}
}
Our dependency injection java services are ready and now we can write our consumer class.
Java Dependency Injection – Service Consumer
We are not required to have base interfaces for consumer classes but I will have a Consumer interface declaring contract for consumer classes.
package com.journaldev.java.dependencyinjection.consumer;
public interface Consumer {
void processMessages(String msg, String rec);
}
My consumer class implementation is like below.
package com.journaldev.java.dependencyinjection.consumer;
import com.journaldev.java.dependencyinjection.service.MessageService;
public class MyDIApplication implements Consumer{
private MessageService service;
public MyDIApplication(MessageService svc){
this.service=svc;
}
@Override
public void processMessages(String msg, String rec){
//do some msg validation, manipulation logic etc
this.service.sendMessage(msg, rec);
}
}
Notice that our application class is just using the service. It does not initialize the service that leads to better “separation of concerns“. Also use of service interface allows us to easily test the application by mocking the MessageService and bind the services at runtime rather than compile time.
Now we are ready to write java dependency injector classes that will initialize the service and also consumer classes.
Java Dependency Injection – Injectors Classes
Let’s have an interface MessageServiceInjector with method declaration that returns the Consumer class.
package com.journaldev.java.dependencyinjection.injector;
import com.journaldev.java.dependencyinjection.consumer.Consumer;
public interface MessageServiceInjector {
public Consumer getConsumer();
}
Now for every service, we will have to create injector classes like below.
package com.journaldev.java.dependencyinjection.injector;
import com.journaldev.java.dependencyinjection.consumer.Consumer;
import com.journaldev.java.dependencyinjection.consumer.MyDIApplication;
import com.journaldev.java.dependencyinjection.service.EmailServiceImpl;
public class EmailServiceInjector implements MessageServiceInjector {
@Override
public Consumer getConsumer() {
return new MyDIApplication(new EmailServiceImpl());
}
}
package com.journaldev.java.dependencyinjection.injector;
import com.journaldev.java.dependencyinjection.consumer.Consumer;
import com.journaldev.java.dependencyinjection.consumer.MyDIApplication;
import com.journaldev.java.dependencyinjection.service.SMSServiceImpl;
public class SMSServiceInjector implements MessageServiceInjector {
@Override
public Consumer getConsumer() {
return new MyDIApplication(new SMSServiceImpl());
}
}
Now let’s see how our client applications will use the application with a simple program.
package com.journaldev.java.dependencyinjection.test;
import com.journaldev.java.dependencyinjection.consumer.Consumer;
import com.journaldev.java.dependencyinjection.injector.EmailServiceInjector;
import com.journaldev.java.dependencyinjection.injector.MessageServiceInjector;
import com.journaldev.java.dependencyinjection.injector.SMSServiceInjector;
public class MyMessageDITest {
public static void main(String[] args) {
String msg = "Hi Pankaj";
String email = "pankaj@abc.com";
String phone = "4088888888";
MessageServiceInjector injector = null;
Consumer app = null;
//Send email
injector = new EmailServiceInjector();
app = injector.getConsumer();
app.processMessages(msg, email);
//Send SMS
injector = new SMSServiceInjector();
app = injector.getConsumer();
app.processMessages(msg, phone);
}
}
As you can see that our application classes are responsible only for using the service. Service classes are created in injectors. Also if we have to further extend our application to allow facebook messaging, we will have to write Service classes and injector classes only.
So dependency injection implementation solved the problem with hard-coded dependency and helped us in making our application flexible and easy to extend. Now let’s see how easily we can test our application class by mocking the injector and service classes.
Java Dependency Injection – JUnit Test Case with Mock Injector and Service
package com.journaldev.java.dependencyinjection.test;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import com.journaldev.java.dependencyinjection.consumer.Consumer;
import com.journaldev.java.dependencyinjection.consumer.MyDIApplication;
import com.journaldev.java.dependencyinjection.injector.MessageServiceInjector;
import com.journaldev.java.dependencyinjection.service.MessageService;
public class MyDIApplicationJUnitTest {
private MessageServiceInjector injector;
@Before
public void setUp(){
//mock the injector with anonymous class
injector = new MessageServiceInjector() {
@Override
public Consumer getConsumer() {
//mock the message service
return new MyDIApplication(new MessageService() {
@Override
public void sendMessage(String msg, String rec) {
System.out.println("Mock Message Service implementation");
}
});
}
};
}
@Test
public void test() {
Consumer consumer = injector.getConsumer();
consumer.processMessages("Hi Pankaj", "pankaj@abc.com");
}
@After
public void tear(){
injector = null;
}
}
As you can see that I am using anonymous classes to mock the injector and service classes and I can easily test my application methods. I am using JUnit 4 for above test class, so make sure it’s in your project build path if you are running above test class.
We have used constructors to inject the dependencies in the application classes, another way is to use setter method to inject dependencies in application classes. For setter method dependency injection, our application class will be implemented like below.
package com.journaldev.java.dependencyinjection.consumer;
import com.journaldev.java.dependencyinjection.service.MessageService;
public class MyDIApplication implements Consumer{
private MessageService service;
public MyDIApplication(){}
//setter dependency injection
public void setService(MessageService service) {
this.service = service;
}
@Override
public void processMessages(String msg, String rec){
//do some msg validation, manipulation logic etc
this.service.sendMessage(msg, rec);
}
}
package com.journaldev.java.dependencyinjection.injector;
import com.journaldev.java.dependencyinjection.consumer.Consumer;
import com.journaldev.java.dependencyinjection.consumer.MyDIApplication;
import com.journaldev.java.dependencyinjection.service.EmailServiceImpl;
public class EmailServiceInjector implements MessageServiceInjector {
@Override
public Consumer getConsumer() {
MyDIApplication app = new MyDIApplication();
app.setService(new EmailServiceImpl());
return app;
}
}
One of the best example of setter dependency injection is Struts2 Servlet API Aware interfaces.
Whether to use Constructor based dependency injection or setter based is a design decision and depends on your requirements. For example, if my application can’t work at all without the service class then I would prefer constructor based DI or else I would go for setter method based DI to use it only when it’s really needed.
Dependency Injection in Java is a way to achieve Inversion of control (IoC) in our application by moving objects binding from compile time to runtime. We can achieve IoC through Factory Pattern, Template Method Design Pattern, Strategy Pattern and Service Locator pattern too.
Spring Dependency Injection, Google Guice and Java EE CDI frameworks facilitate the process of dependency injection through use of Java Reflection API and java annotations. All we need is to annotate the field, constructor or setter method and configure them in configuration xml files or classes.
Benefits of Java Dependency Injection
Some of the benefits of using Dependency Injection in Java are:
Separation of Concerns
Boilerplate Code reduction in application classes because all work to initialize dependencies is handled by the injector component
Configurable components makes application easily extendable
Unit testing is easy with mock objects
Disadvantages of Java Dependency Injection:
If overused, it can lead to maintenance issues because effect of changes are known at runtime.
Dependency injection in java hides the service class dependencies that can lead to runtime errors that would have been caught at compile time.
SLF4J solves most of the problems around latency, "isDebugEnabled", parameterized logging and future proofing.
SL4J is great API and specially parametrized logging is best. Though latency in electronic trading system is proportional to how much you log, SLFJ slightly improves that due to its speed.
"Mapped Diagnostic Context" is essentially a map maintained by the logging framework where the application code provides key-value pairs which can then be inserted by the logging framework in log messages. MDC data can also be highly helpful in filtering messages or triggering certain actions.
SLF4J supports MDC, or mapped diagnostic context. If the underlying logging framework offers MDC functionality, then SLF4J will delegate to the underlying framework's MDC. Note that at this time, only log4j and logback offer MDC functionality. If the underlying framework does not offer MDC, for example java.util.logging, then SLF4J will still store MDC data but the information therein will need to be retrieved by custom user code.
Thus, as a SLF4J user, you can take advantage of MDC information in the presence of log4j or logback, but without forcing these logging frameworks upon your users as dependencies.
https://www.javacodegeeks.com/2012/04/using-slf4j-with-logback-tutorial.html
Using slf4j with logback tutorial April 11th, 2012
The Simple Logging Facade For Java (slf4j) is a simple facade for various logging frameworks, like JDK logging (java.util.logging), log4j, or logback. Even it contains a binding tat will delegate all logger operations to another well known logging facade called jakarta commons logging (JCL).
Logback is the successor of log4j logger API, in fact both projects have the same father, but logback offers some advantages over log4j, like better performance and less memory consumption, automatic reloading of configuration files, or filter capabilities, to cite a few features.
Native implementation of slf4j is logback, thus using both as logger framework implies zero memory and computational overhead.
First we are going to add slf4j and logback into pom as dependencies.
<properties>
<slf4j.version>1.6.4</slf4j.version>
<logback.version>1.0.1</logback.version>
</properties>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>${logback.version}</version>
</dependency>
</dependencies>
Note that three files are required, one for slf4j, and two for logback. The last two dependencies will change depending on you logging framework, if for example you want to still use log4j, instead of having logback dependencies we would have log4j dependency itself and slf4j-log4j12.
Next step is creating the configuration file. Logback supports two formats of configurations files, the traditional way, using XML or using a Groovy DSL style. Let’s start with traditional way, and we are going to create a file called logback.xml into classpath. File name is mandatory, but logback-test.xml is also valid. In case that both files are found in classpath the one ended with -test, will be used.
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoders are assigned the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{5} - %msg%n</pattern>
</encoder>
</appender>
<logger name="com.lordofthejars.foo" level="INFO" additivity="false">
<appender-ref ref="STDOUT" />
</logger>
<!-- Strictly speaking, the level attribute is not necessary since -->
<!-- the level of the root level is set to DEBUG by default. -->
<root level="DEBUG">
<appender-ref ref="STDOUT" />
</root>
</configuration>
In general file is quite intuitive, we are defining the appender (the output of log messages), in this case to console, a pattern, and finally root level logger (DEBUG) and a different level logger (INFO) for classes present in foo package.
Obviously this format is much readable than typical log4j.properties. Recall on additivity attribute, the appender named STDOUT is attached to two loggers, to root and to com.lordofthejars.foo. because the root logger is the ancestor of all loggers, logging request made by com.lordofthejars.foo logger will be output twice. To avoid this behavior you can set additivity attribute to false, and message will be printed only once.
Now let’s create to classes which will use slf4j. First class called BarComponent is created on com.lordofthejars.bar:
public class BarComponent {
private static final Logger logger = LoggerFactory.getLogger(BarComponent.class);
public void bar() {
String name = "lordofthejars";
logger.info("Hello from Bar.");
logger.debug("In bar my name is {}.", name);
}
}
Note two big differences from log4j. The first one is that is no longer required the typical if construction above each log call. The other one is a pair of ‘{}’. Only after evaluating whether to log or not, logback will format the message replacing ‘{}’ with the given string value.
The other one called FooComponent is created on com.lordofthejars.foo:
public class FooComponent {
private static final Logger logger = LoggerFactory.getLogger(FooComponent.class);
public void foo() {
String name = "Alex";
logger.info("Hello from Foo.");
logger.debug("In foo my name is {}.", name);
}
}
And now calling foo and bar method, with previous configuration, the output produced will be:
13:49:59.586 [main] INFO c.l.b.BarComponent - Hello from Bar.
13:49:59.617 [main] DEBUG c.l.b.BarComponent - In bar today is 5/3/2012
13:49:59.618 [main] INFO c.l.f.FooComponent - Hello from Foo.
Notice that debug lines in foo method are not shown. This is ok, because we have set to be in this way.
Next step we are going to take is configuring logback, but instead of using xml approach we are going to use groovy DSL approach. Logback will give preference to groovy configuration over xml configuration, so keep in mind it if you are mixing configuration approaches.
So first thing to do is add groovy as dependency.
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy</artifactId>
<version>${groovy.version}</version>
<scope>runtime</scope>
</dependency>
And then we are going to create the same configuration created previously but in groovy format.
import ch.qos.logback.classic.encoder.PatternLayoutEncoder
import ch.qos.logback.core.ConsoleAppender
import static ch.qos.logback.classic.Level.DEBUG
import static ch.qos.logback.classic.Level.INFO
appender("STDOUT", ConsoleAppender) {
encoder(PatternLayoutEncoder) {
pattern = "%d{HH:mm:ss.SSS} [%thread] %-5level %logger{5} Groovy - %msg%n"
}
}
logger("com.lordofthejars.foo", INFO)
root(DEBUG, ["STDOUT"])
You can identify the same parameters of xml approach but as groovy functions.
http://softwareengineering.stackexchange.com/questions/279690/why-does-the-trace-level-exist-and-when-should-i-use-it-rather-than-debug
Why does the TRACE level exist, and when should I use it rather than DEBUG?
https://logback.qos.ch/manual/configuration.html#cumulative
#detect last foreach loop iteration
http://stackoverflow.com/questions/41591107/detect-last-foreach-loop-iteration
Set<String> names = new HashSet<>();
//some code
int i = 0;
for (String name: names) {
if(i++ == names.size() - 1){
// Last iteration
}
//some code
}
#javascript
var is not global, it's function scoped, and if you define a var variable inside a function, it won't be available outside of that function. Let is BLOCK scoped.
https://www.youtube.com/watch?v=Jakoi0G8lBg