SlideShare une entreprise Scribd logo
1  sur  199
Télécharger pour lire hors ligne
SPRING, JAKARTA EE, CDISPRING, JAKARTA EE, CDI
and otherand otherand other pathologiespathologiespathologies
JAREK RATAJSKIJAREK RATAJSKI
Software Developer, Wizard, AnarchitectSoftware Developer, Wizard, AnarchitectSoftware Developer, Wizard, Anarchitect
at Engenius GmbHat Engenius GmbHat Engenius GmbH
@ Engeniush GmbH@ Engeniush GmbH@ Engeniush GmbH
Yes, we hireYes, we hireYes, we hire
Pros:Pros:Pros:
No table football
Cons:Cons:Cons:
you have to talk to people
I WORK WITH JAVA EE SINCE ~2001I WORK WITH JAVA EE SINCE ~2001
WITH SPRING SINCE 2006WITH SPRING SINCE 2006
I remember EJB-OSS
and huge xmls in Spring
At the moment I amAt the moment I amAt the moment I am making my hands dirty in about 15 various Springmaking my hands dirty in about 15 various Springmaking my hands dirty in about 15 various Spring
and Java EE projectsand Java EE projectsand Java EE projects
I code for only few projects that are notI code for only few projects that are notI code for only few projects that are not SpringSpringSpring
ororor Java EEJava EEJava EE basedbasedbased
I code for only few projects that are notI code for only few projects that are notI code for only few projects that are not SpringSpringSpring
ororor Java EEJava EEJava EE basedbasedbased
including one very critical application (netty based)including one very critical application (netty based)including one very critical application (netty based)
⚠ I like xing production bugs:⚠ I like xing production bugs:⚠ I like xing production bugs:
⚠ I like xing production bugs:⚠ I like xing production bugs:⚠ I like xing production bugs:
Concurrency, security, performance, heisenbugsConcurrency, security, performance, heisenbugsConcurrency, security, performance, heisenbugs
As I have some Java EE, Spring experienceAs I have some Java EE, Spring experienceAs I have some Java EE, Spring experience
As I have some Java EE, Spring experienceAs I have some Java EE, Spring experienceAs I have some Java EE, Spring experience
I think,I think,I think,
As I have some Java EE, Spring experienceAs I have some Java EE, Spring experienceAs I have some Java EE, Spring experience
I think,I think,I think,
they are doing too much harm to your code (architecture)they are doing too much harm to your code (architecture)they are doing too much harm to your code (architecture)
As I have some Java EE, Spring experienceAs I have some Java EE, Spring experienceAs I have some Java EE, Spring experience
I think,I think,I think,
they are doing too much harm to your code (architecture)they are doing too much harm to your code (architecture)they are doing too much harm to your code (architecture)
we have to do betterwe have to do betterwe have to do better
STORY OFSTORY OF GO TOGO TO ((GOTOGOTO))
GO TO STATEMENT CONSIDERED HARMFULGO TO STATEMENT CONSIDERED HARMFUL
March 1968,March 1968,March 1968, Edsger W. DijkstraEdsger W. DijkstraEdsger W. Dijkstra
E.D.E.D.E.D.
For a number of years I have been familiar with theFor a number of years I have been familiar with theFor a number of years I have been familiar with the
observation that the quality of programmers is aobservation that the quality of programmers is aobservation that the quality of programmers is a
decreasing function of the density of go todecreasing function of the density of go todecreasing function of the density of go to
statements in the programs they produce. Morestatements in the programs they produce. Morestatements in the programs they produce. More
recently I discovered why the use of the go torecently I discovered why the use of the go torecently I discovered why the use of the go to
statement has such disastrous e ects, and I becamestatement has such disastrous e ects, and I becamestatement has such disastrous e ects, and I became
convinced that the go to statement should beconvinced that the go to statement should beconvinced that the go to statement should be
abolished from all "higher level" programmingabolished from all "higher level" programmingabolished from all "higher level" programming
languages (i.e. everything except, perhaps, plainlanguages (i.e. everything except, perhaps, plainlanguages (i.e. everything except, perhaps, plain
machine code). At that time I did not attach toomachine code). At that time I did not attach toomachine code). At that time I did not attach too
much importance to this discovery; I now submit mymuch importance to this discovery; I now submit mymuch importance to this discovery; I now submit my
considerations for publication because in veryconsiderations for publication because in veryconsiderations for publication because in very
recent discussions in which the subject turned up, Irecent discussions in which the subject turned up, Irecent discussions in which the subject turned up, I
have been urged to do so.have been urged to do so.have been urged to do so.
GOT0 CONSIDERED HARMFUL - CONSIDERED HARMFULGOT0 CONSIDERED HARMFUL - CONSIDERED HARMFUL
March 1987, Frank RubinMarch 1987, Frank RubinMarch 1987, Frank Rubin
F.R.F.R.F.R.
GOTO-less programs are harder and costlier toGOTO-less programs are harder and costlier toGOTO-less programs are harder and costlier to
create, test, and modify.create, test, and modify.create, test, and modify.
F.R.F.R.F.R.
AsAsAs I introduce GOTOs to untangleI introduce GOTOs to untangleI introduce GOTOs to untangle each deeplyeach deeplyeach deeply
nested mess of code,nested mess of code,nested mess of code, I have found that the numberI have found that the numberI have found that the number
of lines of code often drops byof lines of code often drops byof lines of code often drops by 20-25 percent,20-25 percent,20-25 percent,
F.R.F.R.F.R.
I am aware that some awful programs have beenI am aware that some awful programs have beenI am aware that some awful programs have been
written usingwritten usingwritten using GOTOs. This is often the fault ofGOTOs. This is often the fault ofGOTOs. This is often the fault of thethethe
language (because it lackslanguage (because it lackslanguage (because it lacks other constructs), or theother constructs), or theother constructs), or the
text editor (because it lacks a blocktext editor (because it lacks a blocktext editor (because it lacks a block move). With amove). With amove). With a
proper languageproper languageproper language and editor, and adequateand editor, and adequateand editor, and adequate
instruction in the use of GOTO, thisinstruction in the use of GOTO, thisinstruction in the use of GOTO, this should not be ashould not be ashould not be a
consideration.consideration.consideration.
somesomesome C# .NetC# .NetC# .Net code presented to proove howcode presented to proove howcode presented to proove how COOLCOOLCOOL goto is (at polishgoto is (at polishgoto is (at polish
4programmers message board)4programmers message board)4programmers message board)
private static bool TryParseSByteD(ReadOnlySpan<byte> source, out sbyte value, out int bytesConsumed)
{
if (source.Length < 1)
goto FalseExit;
int sign = 1;
int index = 0;
int num = source[index];
if (num == '-')
{
sign = -1;
index++;
if ((uint)index >= (uint)source.Length)
goto FalseExit;
num = source[index];
}
else if (num == '+')
{
index++;
if ((uint)index >= (uint)source.Length)
goto FalseExit;
num = source[index];
}
int answer = 0;
if (ParserHelpers.IsDigit(num))
{
if (num == '0')
{
do
{
index++;
if ((uint)index >= (uint)source.Length)
goto Done;
num = source[index];
} while (num == '0');
if (!ParserHelpers.IsDigit(num))
goto Done;
}
answer = num - '0';
index++;
if ((uint)index >= (uint)source.Length)
goto Done;
num = source[index];
if (!ParserHelpers.IsDigit(num))
goto Done;
index++;
answer = 10 * answer + num - '0';
// Potential overflow
if ((uint)index >= (uint)source.Length)
goto Done;
num = source[index];
ON A SOMEWHAT DISAPPOINTING CORRESPONDENCEON A SOMEWHAT DISAPPOINTING CORRESPONDENCE
May 1987, Edsger W. DijkstraMay 1987, Edsger W. DijkstraMay 1987, Edsger W. Dijkstra
E.D.E.D.E.D.
By my standards, a competent professionalBy my standards, a competent professionalBy my standards, a competent professional
programmer in 1987programmer in 1987programmer in 1987
should recognize that Rubin’s problem asks to be
solved by a nested application of the same
algorithm;
should know the theorem of “The bounded linear
search”;
should be able to derive that theorem and its
proof;
should not hesitate to use it;
should not waste his time in pointing out that the
boolean variable d is super uous;
should keep his repetitions simple and
disentangled;
etc. . .
It is typically possible to show how greatIt is typically possible to show how greatIt is typically possible to show how great GO TOGO TOGO TO is,is,is, on a small selectedon a small selectedon a small selected
piece of codepiece of codepiece of code
it is performantit is performantit is performant
write nowwrite nowwrite now - jump anywhere- jump anywhere- jump anywhere
BUTBUT
BrokenBrokenBroken local reasoninglocal reasoninglocal reasoning
BrokenBrokenBroken local reasoninglocal reasoninglocal reasoning
how much code do you have to read when something does not workhow much code do you have to read when something does not workhow much code do you have to read when something does not work
MAINSTREAM INDUSTRY STOPPED USINGMAINSTREAM INDUSTRY STOPPED USING "GOTO""GOTO" DECADESDECADES
AGOAGO
Costs (risks) are greater thanCosts (risks) are greater thanCosts (risks) are greater than pro tspro tspro ts
THE ENDTHE END
GOTO 10GOTO 10
10:10: BeansBeans (AS YOU KNOW) ARE(AS YOU KNOW) ARE "GOTOs""GOTOs" OF JAVAOF JAVA
WHAT IS AWHAT IS A BeanBean??
Forget about classicForget about classicForget about classic JavaBeansJavaBeansJavaBeans
Forget about classicForget about classicForget about classic JavaBeansJavaBeansJavaBeans
This is closed topic,This is closed topic,This is closed topic, we don't gowe don't gowe don't go there anymorethere anymorethere anymore
SPRING BEANS, JAVA EE BEANS, CDI BEANS, JSF,SPRING BEANS, JAVA EE BEANS, CDI BEANS, JSF,
JPA...JPA...
BEAN == MUTILATED, CRIPPLED CLASS(OBJECT) IN JAVABEAN == MUTILATED, CRIPPLED CLASS(OBJECT) IN JAVA
BEAN == MUTILATED, CRIPPLED CLASS(OBJECT) IN JAVABEAN == MUTILATED, CRIPPLED CLASS(OBJECT) IN JAVA
Looks like normal object, but does not behave (like) normalLooks like normal object, but does not behave (like) normalLooks like normal object, but does not behave (like) normal
BEAN == MUTILATED, CRIPPLED CLASS(OBJECT) IN JAVABEAN == MUTILATED, CRIPPLED CLASS(OBJECT) IN JAVA
Looks like normal object, but does not behave (like) normalLooks like normal object, but does not behave (like) normalLooks like normal object, but does not behave (like) normal
BEAN == MUTILATED, CRIPPLED CLASS(OBJECT) IN JAVABEAN == MUTILATED, CRIPPLED CLASS(OBJECT) IN JAVA
Looks like normal object, but does not behave (like) normalLooks like normal object, but does not behave (like) normalLooks like normal object, but does not behave (like) normal
Not instantiated by new
BEAN == MUTILATED, CRIPPLED CLASS(OBJECT) IN JAVABEAN == MUTILATED, CRIPPLED CLASS(OBJECT) IN JAVA
Looks like normal object, but does not behave (like) normalLooks like normal object, but does not behave (like) normalLooks like normal object, but does not behave (like) normal
Not instantiated by new
BEAN == MUTILATED, CRIPPLED CLASS(OBJECT) IN JAVABEAN == MUTILATED, CRIPPLED CLASS(OBJECT) IN JAVA
Looks like normal object, but does not behave (like) normalLooks like normal object, but does not behave (like) normalLooks like normal object, but does not behave (like) normal
Not instantiated by new
there are special rules, limitations, conventions on use
BEANS, BUT WHY?BEANS, BUT WHY?
20: DISASTER NO. 120: DISASTER NO. 1
INJECTIONSINJECTIONS
dependency injectiondependency injectiondependency injection - what is a DI?- what is a DI?- what is a DI?
WikipediaWikipediaWikipedia
In software engineering, dependency injection is aIn software engineering, dependency injection is aIn software engineering, dependency injection is a
technique whereby one object supplies thetechnique whereby one object supplies thetechnique whereby one object supplies the
dependencies of another object. A "dependency" isdependencies of another object. A "dependency" isdependencies of another object. A "dependency" is
an object that can be used, for example a service.an object that can be used, for example a service.an object that can be used, for example a service.
Instead of a client specifying which service it willInstead of a client specifying which service it willInstead of a client specifying which service it will
use, something tells the client what service to use.use, something tells the client what service to use.use, something tells the client what service to use.
The "injection" refers to the passing of a dependencyThe "injection" refers to the passing of a dependencyThe "injection" refers to the passing of a dependency
(a service) into the object (a client) that would use it.(a service) into the object (a client) that would use it.(a service) into the object (a client) that would use it.
The service is made part of the client's state.[1]The service is made part of the client's state.[1]The service is made part of the client's state.[1]
Passing the service to the client, rather thanPassing the service to the client, rather thanPassing the service to the client, rather than
allowing a client to build or nd the service, is theallowing a client to build or nd the service, is theallowing a client to build or nd the service, is the
fundamental requirement of the pattern.fundamental requirement of the pattern.fundamental requirement of the pattern.
Passing the service to the client, rather thanPassing the service to the client, rather thanPassing the service to the client, rather than
allowing a client to build or nd the service, is theallowing a client to build or nd the service, is theallowing a client to build or nd the service, is the
fundamental requirement of the pattern.fundamental requirement of the pattern.fundamental requirement of the pattern.
Do we have aDo we have aDo we have a dependency injectiondependency injectiondependency injection here?here?here?
class MyService {
private final DbRepo db;
public MyService() {
this.db = new DbRepo("jdbc://url")
}
}
Do we have aDo we have aDo we have a dependency injectiondependency injectiondependency injection here?here?here?
class MyService {
private final DbRepo db;
public MyService(DbRepo db) {
this.db = db;
}
}
MyService serviceProvider() {
var db = new DbRepo("jdbc://url")
return MyService(db)
}
https://sites.google.com/site/unclebobconsultingllc/blogs-by-robert-https://sites.google.com/site/unclebobconsultingllc/blogs-by-robert-https://sites.google.com/site/unclebobconsultingllc/blogs-by-robert-
martin/dependency-injection-inversionmartin/dependency-injection-inversionmartin/dependency-injection-inversion
Dependency Injection doesn’t require a framework;Dependency Injection doesn’t require a framework;Dependency Injection doesn’t require a framework;
it just requires that you invert your dependenciesit just requires that you invert your dependenciesit just requires that you invert your dependencies
and then construct and pass your arguments toand then construct and pass your arguments toand then construct and pass your arguments to
deeper layers.deeper layers.deeper layers.
Framework (IoC container) lets youFramework (IoC container) lets youFramework (IoC container) lets you injectinjectinject at aat aat a small costsmall costsmall cost
Framework (IoC container) lets youFramework (IoC container) lets youFramework (IoC container) lets you injectinjectinject at aat aat a small costsmall costsmall cost
Framework (IoC container) lets youFramework (IoC container) lets youFramework (IoC container) lets you injectinjectinject at aat aat a small costsmall costsmall cost
It is in fact technical debt - you will pay laterIt is in fact technical debt - you will pay laterIt is in fact technical debt - you will pay later
Typical Spring (DI) application architectureTypical Spring (DI) application architectureTypical Spring (DI) application architecture (simpli ed)(simpli ed)(simpli ed)
Repository in Controller - no problemRepository in Controller - no problemRepository in Controller - no problem
Repository in Controller - no problemRepository in Controller - no problemRepository in Controller - no problem
HttpRequest in Persistence layer - no problemHttpRequest in Persistence layer - no problemHttpRequest in Persistence layer - no problem
Repository in Controller - no problemRepository in Controller - no problemRepository in Controller - no problem
HttpRequest in Persistence layer - no problemHttpRequest in Persistence layer - no problemHttpRequest in Persistence layer - no problem
Injecting anything anywhere - no problemInjecting anything anywhere - no problemInjecting anything anywhere - no problem
Repository in Controller - no problemRepository in Controller - no problemRepository in Controller - no problem
HttpRequest in Persistence layer - no problemHttpRequest in Persistence layer - no problemHttpRequest in Persistence layer - no problem
Injecting anything anywhere - no problemInjecting anything anywhere - no problemInjecting anything anywhere - no problem
Bean transferred diseases - gratisBean transferred diseases - gratisBean transferred diseases - gratis
Beans just pretend they are not infamousBeans just pretend they are not infamousBeans just pretend they are not infamous SingletonSingletonSingletonsss
Only bad developers do thisOnly bad developers do thisOnly bad developers do this
Only bad developers do thisOnly bad developers do thisOnly bad developers do this
Only bad developers do thisOnly bad developers do thisOnly bad developers do this
oh, really?oh, really?oh, really?
It is likeIt is likeIt is like GO TOGO TOGO TO
Sooner or later someone will make a shortcut an hour before DEMOSooner or later someone will make a shortcut an hour before DEMOSooner or later someone will make a shortcut an hour before DEMO
An it will stay like that -An it will stay like that -An it will stay like that - foreverforeverforever
Because, the most important things in agile are:Because, the most important things in agile are:Because, the most important things in agile are:
Sooner or later someone will make a shortcut an hour before DEMOSooner or later someone will make a shortcut an hour before DEMOSooner or later someone will make a shortcut an hour before DEMO
An it will stay like that -An it will stay like that -An it will stay like that - foreverforeverforever
Because, the most important things in agile are:Because, the most important things in agile are:Because, the most important things in agile are:
VelocityVelocityVelocity and niceand niceand nice burndown chartsburndown chartsburndown charts
LOBOLOBO
Level of Beans obscurityLevel of Beans obscurityLevel of Beans obscurity
(same for Jakarta EE -(same for Jakarta EE -(same for Jakarta EE - CDICDICDI @Inject@Inject@Inject, EJB, EJB, EJB @EJB@EJB@EJB ...)...)...)
It is evenIt is evenIt is even pro containerspro containerspro containers argument !argument !argument !
Would you write all those hundreds of injectionsWould you write all those hundreds of injectionsWould you write all those hundreds of injections
manually?manually?manually?
SolutionSolutionSolution
Step 0Step 0Step 0
class A {
@Autowired
Xx;
@Autowired
Y y;
@AUtowired
Z z;
}
Step 1Step 1Step 1
((( )))
class A {
final X x;
final Y y;
final Z z;
@Autowired
A(X x, Y y, Z z) {
this.x =x; this.y = y; this.z = z;
}
}
http://olivergierke.de/2013/11/why- eld-injection-is-evil/http://olivergierke.de/2013/11/why- eld-injection-is-evil/http://olivergierke.de/2013/11/why- eld-injection-is-evil/
Step 2Step 2Step 2
class A {
final X x;
final Y y;
final Z z;
//@Autowired
A(X x, Y y, Z z) {
this.x =x; this.y = y; this.z = z;
}
}
BACK TO CODING SCHOOL:BACK TO CODING SCHOOL:
BACK TO CODING SCHOOL:BACK TO CODING SCHOOL:
If code is repeated - extract it to functionIf code is repeated - extract it to functionIf code is repeated - extract it to function
BACK TO CODING SCHOOL:BACK TO CODING SCHOOL:
If code is repeated - extract it to functionIf code is repeated - extract it to functionIf code is repeated - extract it to function
Sections of repeatingSections of repeatingSections of repeating newnewnew can be as well extractedcan be as well extractedcan be as well extracted
BACK TO CODING SCHOOL:BACK TO CODING SCHOOL:
If code is repeated - extract it to functionIf code is repeated - extract it to functionIf code is repeated - extract it to function
Sections of repeatingSections of repeatingSections of repeating newnewnew can be as well extractedcan be as well extractedcan be as well extracted
Use factories / providersUse factories / providersUse factories / providers
BACK TO CODING SCHOOL:BACK TO CODING SCHOOL:
If code is repeated - extract it to functionIf code is repeated - extract it to functionIf code is repeated - extract it to function
Sections of repeatingSections of repeatingSections of repeating newnewnew can be as well extractedcan be as well extractedcan be as well extracted
Use factories / providersUse factories / providersUse factories / providers
Too many arguements in constructor? Split a class in two (or three) (!)Too many arguements in constructor? Split a class in two (or three) (!)Too many arguements in constructor? Split a class in two (or three) (!)
PLENTY OF "BEANS" HAVE EXACTLY ONEPLENTY OF "BEANS" HAVE EXACTLY ONE
IMPLEMENTATIONIMPLEMENTATION
PLENTY OF "BEANS" HAVE EXACTLY ONEPLENTY OF "BEANS" HAVE EXACTLY ONE
IMPLEMENTATIONIMPLEMENTATION
Services, Controllers...Services, Controllers...Services, Controllers...
PLENTY OF "BEANS" HAVE EXACTLY ONEPLENTY OF "BEANS" HAVE EXACTLY ONE
IMPLEMENTATIONIMPLEMENTATION
Services, Controllers...Services, Controllers...Services, Controllers...
You don't need to make everything injectableYou don't need to make everything injectableYou don't need to make everything injectable
EXAMPLE (IN KOTLIN + VAVR)EXAMPLE (IN KOTLIN + VAVR)
data class StonesModule(
private val seq: DbSequence = DbSequence(),
val stoneRepo: Lazy<StoneRepo> = Lazy.of { StoneRepo(seq) },
val stoneService: Lazy<StoneService> = Lazy.of {StoneService
val stoneRest: Lazy<StoneRest> = Lazy.of {StoneRest(stoneSer
) //this is Kotlin uber constructor
// somewhere else
val myModule = StoneRepo( stoneRepo = Lazy.of{MyRepo()})
val service = myModule.stoneService.get()
"MANUAL" DI VS FRAMEWORK"MANUAL" DI VS FRAMEWORK
Manual DI vs container IoC
small pain every day <--> no problem for months - the disaster
tree like structure <--> ball of mud (messy cake)
3 - 6 deps per class <--> 5 - 18 deps per class (LOBO)
Manual DIManual DIManual DI
THERE ARE BEANS WORSE THAN SINGLETONS....THERE ARE BEANS WORSE THAN SINGLETONS....
THERE ARE BEANS WORSE THAN SINGLETONS....THERE ARE BEANS WORSE THAN SINGLETONS....
Request scoped
THERE ARE BEANS WORSE THAN SINGLETONS....THERE ARE BEANS WORSE THAN SINGLETONS....
Request scoped
Session scoped
THERE ARE BEANS WORSE THAN SINGLETONS....THERE ARE BEANS WORSE THAN SINGLETONS....
Request scoped
Session scoped
ThreadLocal based
THERE ARE BEANS WORSE THAN SINGLETONS....THERE ARE BEANS WORSE THAN SINGLETONS....
Request scoped
Session scoped
ThreadLocal based
Those are in factThose are in factThose are in fact global variablesglobal variablesglobal variables
private C method1( A a, B b) {
//uses a, b, and this. fields
this.serviceX.method2(a); //does not use `b`
this.serviceY.method3(b); //method does not use `a`
}
@Component
@Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
class TrollService {
public A getA() {
return a;
}
public void setA(A a) {
this.a = a;
}
private A a;
}
@Service
public class ServiceX {
@Autowired
private TrollService trollService;
void method2(A a) {
trollService.setA(a);
}
}
In spring based projects this isIn spring based projects this isIn spring based projects this is normalnormalnormal
(especially in Spring batch)(especially in Spring batch)(especially in Spring batch)
BrokenBrokenBroken Local reasoningLocal reasoningLocal reasoning
OUTCOME:OUTCOME:
Many of small, reasonable changesMany of small, reasonable changesMany of small, reasonable changes can break your systemcan break your systemcan break your system
OUTCOME:OUTCOME:
Many of small, reasonable changesMany of small, reasonable changesMany of small, reasonable changes can break your systemcan break your systemcan break your system
and tests are still green (because they test only mocks)and tests are still green (because they test only mocks)and tests are still green (because they test only mocks)
OUTCOME:OUTCOME:
Many of small, reasonable changesMany of small, reasonable changesMany of small, reasonable changes can break your systemcan break your systemcan break your system
and tests are still green (because they test only mocks)and tests are still green (because they test only mocks)and tests are still green (because they test only mocks)
Sleep well, all yourSleep well, all yourSleep well, all your tests are greentests are greentests are green
Slaying Sacred Cows: Deconstructing Dependency InjectionSlaying Sacred Cows: Deconstructing Dependency InjectionSlaying Sacred Cows: Deconstructing Dependency Injection
Tomer GabelTomer GabelTomer Gabel
GOTO 2005GOTO 2005
2005:2005: DISASTER NO. 2DISASTER NO. 2
ASPECTSASPECTS
@Transactional@Transactional
WhenWhenWhen @Transactional@Transactional@Transactional does not work?does not work?does not work?
WhenWhenWhen @Transactional@Transactional@Transactional does not work?does not work?does not work?
private method
WhenWhenWhen @Transactional@Transactional@Transactional does not work?does not work?does not work?
private method
public, but this.call(...)
WhenWhenWhen @Transactional@Transactional@Transactional does not work?does not work?does not work?
private method
public, but this.call(...)
object instantiated with new
WhenWhenWhen @Transactional@Transactional@Transactional does not work?does not work?does not work?
private method
public, but this.call(...)
object instantiated with new
kotlin nal class/method (*)
WhenWhenWhen @Transactional@Transactional@Transactional does not work?does not work?does not work?
private method
public, but this.call(...)
object instantiated with new
kotlin nal class/method (*)
called in other thread (parallelStream(), future)
WhenWhenWhen @Transactional@Transactional@Transactional does not work?does not work?does not work?
private method
public, but this.call(...)
object instantiated with new
kotlin nal class/method (*)
called in other thread (parallelStream(), future)
troll aspekt (@Trollsactional)
WhenWhenWhen @Transactional@Transactional@Transactional does not work?does not work?does not work?
private method
public, but this.call(...)
object instantiated with new
kotlin nal class/method (*)
called in other thread (parallelStream(), future)
troll aspekt (@Trollsactional)
missing jar on server
ADDADD JPA MAGIC ON TOP OF THATJPA MAGIC ON TOP OF THAT
other magic Beans
managed
detached
dirty check
proxy
ADDADD TRANSACTION ISOLATION LEVEL ASSOCIATED ISSUESTRANSACTION ISOLATION LEVEL ASSOCIATED ISSUES
A.C.I.D.A.C.I.D.
Spring withSpring withSpring with @Transactional@Transactional@Transactional andandand JPA, and Database all togetherJPA, and Database all togetherJPA, and Database all together
IfIfIf @Transactional@Transactional@Transactional does not work - where do you put a breakpoint?does not work - where do you put a breakpoint?does not work - where do you put a breakpoint?
All aspects induce similar problems:All aspects induce similar problems:All aspects induce similar problems:
@Secured
@RolesAllowed
@Cacheable
@Lock
...
All aspects induce similar problems:All aspects induce similar problems:All aspects induce similar problems:
@Secured
@RolesAllowed
@Cacheable
@Lock
...
Can your company accept that those aspects may beCan your company accept that those aspects may beCan your company accept that those aspects may be not active onnot active onnot active on
productionproductionproduction???
All aspects induce similar problems:All aspects induce similar problems:All aspects induce similar problems:
@Secured
@RolesAllowed
@Cacheable
@Lock
...
Can your company accept that those aspects may beCan your company accept that those aspects may beCan your company accept that those aspects may be not active onnot active onnot active on
productionproductionproduction???
after small refactoring ?after small refactoring ?after small refactoring ?
All aspects induce similar problems:All aspects induce similar problems:All aspects induce similar problems:
@Secured
@RolesAllowed
@Cacheable
@Lock
...
Can your company accept that those aspects may beCan your company accept that those aspects may beCan your company accept that those aspects may be not active onnot active onnot active on
productionproductionproduction???
after small refactoring ?after small refactoring ?after small refactoring ?
Those are just NOTThose are just NOTThose are just NOT edge casesedge casesedge cases
It happens more often than you thinkIt happens more often than you thinkIt happens more often than you think
Some of the problems (like async) are solved by another set ofSome of the problems (like async) are solved by another set ofSome of the problems (like async) are solved by another set of
annotationsannotationsannotations
@AspectJ,
@PostConstruct,
@EnableAsync,
@EnableScheduling,
@NoRepositoryBean
Bean based development - a gentle introductionBean based development - a gentle introductionBean based development - a gentle introduction
MAGIC IN CODEMAGIC IN CODE
MAGIC IN CODEMAGIC IN CODE
actually false (useless) de nitionactually false (useless) de nitionactually false (useless) de nition
MAGIC IN CODEMAGIC IN CODE
actually false (useless) de nitionactually false (useless) de nitionactually false (useless) de nition
THINGS, WE DO NOTTHINGS, WE DO NOT
UNDERSTANDUNDERSTAND
MAGIC INMAGIC IN CODECODE
MAGIC INMAGIC IN CODECODE
practical de nition (v2.0practical de nition (v2.0practical de nition (v2.0 stable)stable)stable)
MAGIC INMAGIC IN CODECODE
practical de nition (v2.0practical de nition (v2.0practical de nition (v2.0 stable)stable)stable)
THINGS,THINGS, THAT DO NOTTHAT DO NOT
COMPOSE SAFELYCOMPOSE SAFELY
John De GoesJohn De GoesJohn De Goes
John de Goes (again)John de Goes (again)John de Goes (again)
Magic is a feature with non-compositionalMagic is a feature with non-compositionalMagic is a feature with non-compositional
semantics that succeeds in making thesemantics that succeeds in making thesemantics that succeeds in making the commoncommoncommon
case easy, at the cost of making the uncommoncase easy, at the cost of making the uncommoncase easy, at the cost of making the uncommon
cases surprising, impossible, or ridiculouslycases surprising, impossible, or ridiculouslycases surprising, impossible, or ridiculously
complex.complex.complex.
MAGICMAGIC
Dynamic proxy
Thread local
Runtime re ection
Instrumentation
bytecode manipulation
Stringly typed annotations
@Retryable
void myMethod () {
}
@Transactional
void myMethod () {
}
@Transactional
@Retryable
void myMethod () {
}
Is retry inside transaction or transaction inside retry?Is retry inside transaction or transaction inside retry?Is retry inside transaction or transaction inside retry?
@Transactional
@Retryable
void myMethod () {
}
Is retry inside transaction or transaction inside retry?Is retry inside transaction or transaction inside retry?Is retry inside transaction or transaction inside retry?
cache?, security? -> have funcache?, security? -> have funcache?, security? -> have fun
@Transactional
@Retryable
void myMethod () {
}
(hidden) cost of beans magic:(hidden) cost of beans magic:(hidden) cost of beans magic:
Heisenbugs
Stopped development
Unrealistic tests ( no aspects covered)
Slow tests (with aspects)
Overmocking (aka Mocksturbation, ...sorry)
Fear of refactoring
classpath / classloader disasters (on application servers)
problem with new java versions (not in Spring)
ugly architecture with shortcuts
SPRING IS NOT SIMPLESPRING IS NOT SIMPLE
GOTO 666GOTO 666
666: MY TOP 3 - MOST666: MY TOP 3 - MOST
DANGEROUS (MAGIC) TOOLSDANGEROUS (MAGIC) TOOLS
3. JPA3. JPA
void method(User user) {
user.setName("Irek"); //will be saved?
user.getGroups().forEach(...); //will work?
}
3. JPA3. JPA
Depends: isDepends: isDepends: is bean managed (tracked in JPA session),bean managed (tracked in JPA session),bean managed (tracked in JPA session),
void method(User user) {
user.setName("Irek"); //will be saved?
user.getGroups().forEach(...); //will work?
}
3. JPA3. JPA
Depends: isDepends: isDepends: is bean managed (tracked in JPA session),bean managed (tracked in JPA session),bean managed (tracked in JPA session),
waswaswas getGroupsgetGroupsgetGroups called before?called before?called before?
void method(User user) {
user.setName("Irek"); //will be saved?
user.getGroups().forEach(...); //will work?
}
JPA Totally breaksJPA Totally breaksJPA Totally breaks local reasoninglocal reasoninglocal reasoning
People generally know SQLPeople generally know SQLPeople generally know SQL
ThenThenThen spend hours translating SQL to JPAspend hours translating SQL to JPAspend hours translating SQL to JPA
People generally know SQLPeople generally know SQLPeople generally know SQL
ThenThenThen spend hours translating SQL to JPAspend hours translating SQL to JPAspend hours translating SQL to JPA
And they useAnd they useAnd they use .save().save().save() for updatesfor updatesfor updates
People generally know SQLPeople generally know SQLPeople generally know SQL
ThenThenThen spend hours translating SQL to JPAspend hours translating SQL to JPAspend hours translating SQL to JPA
And they useAnd they useAnd they use .save().save().save() for updatesfor updatesfor updates
Which means probably - they have no clueWhich means probably - they have no clueWhich means probably - they have no clue
2. APPLICATION SERVERS2. APPLICATION SERVERS
Websphere, JBoss, Tomcat
Classpath problems
vendor lock-in / java version lock-in
lost in debug
testability(*) way worse than in Spring (I am looking at you
Arquillian)
1. JSF1. JSF
Maybe not the worst web framework ever doneMaybe not the worst web framework ever doneMaybe not the worst web framework ever done
ButButBut it sets the bar pretty highit sets the bar pretty highit sets the bar pretty high (for evil ones)(for evil ones)(for evil ones)
SessionScope hell
disaster in phases
resource consumption (Memory)
funny integration problems with other Beans
HOW ALL THAT HAPPENED?HOW ALL THAT HAPPENED?
Long time ago...Long time ago...Long time ago...
JAVA EE (1.X, 2.X)JAVA EE (1.X, 2.X)
Enterprise Java Bean - remote objects (better CORBA/RMI)
No one simply crates remote objects by new
Java EE/EJB - RMI on steroids
distributed transactions
2 phase commit
security in remote calls
SERVLETSSERVLETS
Classpath scan
instantiation by a container
default constructor
How can you test it?How can you test it?How can you test it?
public class HelloWorld extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResp
throws ServletException, IOException {
PrintWriter out = response.getWriter();
out.println("<h1>" + message + "</h1>");
}
}
ONCE WE HAD NO GENERICS (BEFORE JAVA 5)ONCE WE HAD NO GENERICS (BEFORE JAVA 5)
//java 5
interface Provider<T> {
T getService();
}
//java 1.4
interface Provider {
Object getService();
}
NO LAMBDAS (BEFORENO LAMBDAS (BEFORE JAVA 8)JAVA 8)
"Aspect" done in a proper way"Aspect" done in a proper way"Aspect" done in a proper way
void <R> R doInTranasction( Funtion<DBTRansaction, R> code) {
var trx = b.beginTransaction();
try {
var result = code.apply(trx);
trx.commit();
return result;
} catch (...) {
trx.rollback();
throw ...
}
}
AT THE TIME OF JAVA 1.4AT THE TIME OF JAVA 1.4
Spring was e cient way of creating web applicationsSpring was e cient way of creating web applicationsSpring was e cient way of creating web applications
Up to java 7 there were not that many sensible alternativesUp to java 7 there were not that many sensible alternativesUp to java 7 there were not that many sensible alternatives
From javaFrom javaFrom java 8 on8 on8 on
From javaFrom javaFrom java 8 on8 on8 on
We can use lambdas to provide similar functionality as aspects in aWe can use lambdas to provide similar functionality as aspects in aWe can use lambdas to provide similar functionality as aspects in a
compile safe waycompile safe waycompile safe way - without magic- without magic- without magic
From javaFrom javaFrom java 8 on8 on8 on
We can use lambdas to provide similar functionality as aspects in aWe can use lambdas to provide similar functionality as aspects in aWe can use lambdas to provide similar functionality as aspects in a
compile safe waycompile safe waycompile safe way - without magic- without magic- without magic
We have mature alternatives to servlets (netty, ratpack, sparkjava,We have mature alternatives to servlets (netty, ratpack, sparkjava,We have mature alternatives to servlets (netty, ratpack, sparkjava,
spring web ux)spring web ux)spring web ux)
PSYCHOLOGICAL ASPECTSPSYCHOLOGICAL ASPECTS
everybody Java EE / Spring
magic is great (it worked again, miracle, wow)
Stockholm syndrome
developers ignore costs (risks)
SOLUTIONSSOLUTIONS
STEP 1STEP 1
Drop application serversDrop application serversDrop application servers
Make Jar not War (Make Jar not War (Make Jar not War ( SpringBootSpringBootSpringBoot is good for a start)is good for a start)is good for a start)
use Kotlinuse Kotlinuse Kotlin
use vavr.iouse vavr.iouse vavr.io
STEP 2STEP 2
Hold your BeansHold your BeansHold your Beans
Use Beans where really neededUse Beans where really neededUse Beans where really needed
(example -> only(example -> only(example -> only Jax-RS annotations andJax-RS annotations andJax-RS annotations and @Controllers@Controllers@Controllers)))
Only constructors for DIOnly constructors for DIOnly constructors for DI
STEP 3STEP 3
(fun starts)(fun starts)(fun starts)
Drop JPADrop JPADrop JPA
Try:Try:Try: JOOQ, QueryDSL and alternativesJOOQ, QueryDSL and alternativesJOOQ, QueryDSL and alternatives
STEP 4STEP 4
Go functionsGo functionsGo functions
Spring WebFlux (withoutSpring WebFlux (withoutSpring WebFlux (without beans)beans)beans)
class WisniaServer {
fun start() {
val route = router {
GET("/hello", handle(::printHello))
GET("/helloUser", secure(handle(::printlHelloForUser)))
}
val httpHandler = RouterFunctions.toHttpHandler(route)
val adapter = ReactorHttpHandlerAdapter(httpHandler)
val server = HttpServer
.create()
.host("localhost")
.port(8080)
.handle(adapter)
.bindNow()
println("press enter")
readLine()
server.disposeNow()
}
}
This line:This line:This line:
secure(handle(::printlHelloForUser)))
This all works nicelyThis all works nicelyThis all works nicely in:in:in:
This all works nicelyThis all works nicelyThis all works nicely in:in:in:
SPRINGSPRING
This all works nicelyThis all works nicelyThis all works nicely in:in:in:
SPRINGSPRING
SPRING WEBFLUXSPRING WEBFLUX
This all works nicelyThis all works nicelyThis all works nicely in:in:in:
SPRINGSPRING
SPRING WEBFLUXSPRING WEBFLUX
FullyFullyFully functionalfunctionalfunctional syntax, no beans, no annotations, no aspects neededsyntax, no beans, no annotations, no aspects neededsyntax, no beans, no annotations, no aspects needed
No classpath scanning -> SpringWeb ux starts in 200msNo classpath scanning -> SpringWeb ux starts in 200msNo classpath scanning -> SpringWeb ux starts in 200ms
Ratpack (alternative) starts in 10msRatpack (alternative) starts in 10msRatpack (alternative) starts in 10ms
Testing ofTesting ofTesting of functionalfunctionalfunctional applications is fast and easyapplications is fast and easyapplications is fast and easy
var app = Application(withMyTestDB).start();
var result = app.myApiCall();
assertEquals(expectedResult, result);
STEP 5 (REAL FUN)STEP 5 (REAL FUN)
Go monadsGo monadsGo monads
Transaction is a monadTransaction is a monadTransaction is a monad
STEP 5 (REAL FUN)STEP 5 (REAL FUN)
Go monadsGo monadsGo monads
Transaction is a monadTransaction is a monadTransaction is a monad
Example usingExample usingExample using NeeNeeNee project for aspectsproject for aspectsproject for aspects
fun addNewStone(newStone: StoneData) = seq.next().flatMap {
addStone(it, newStone)
}
private fun addStone(stoneId : Long, newStone: StoneData)
= Nee.constP(transactional) { jdbcProvider ->
val dsl = DSL.using(jdbcProvider.getConnection().getResource())
val insertedRows = dsl.insertInto(Stones.STONES)
.values(stoneId, newStone.name, newStone.price)
.execute()
if (insertedRows == 1) {
Option.some(stoneId)
} else {
Option.none()
}
}
Instead of writing:Instead of writing:Instead of writing:
Write this:Write this:Write this:
class Hasiok {
@Resource
val jdbcConnection: Connection
@Transactional
@Secure
@Cacheable
@Retryable
fun f(p:P) {
//code
}
}
class Hasiok {
private val f = {jdbcConnection:Connection ->
{p: P ->
//code
}
}
val enterprisyF = Nee.pure(
secure
.and(retryable)
.and(cacheable)
.and(transactional), f)
}
GOTO 59999GOTO 59999
SUMMARYSUMMARY
We need time to adopt to new things /We need time to adopt to new things /We need time to adopt to new things / conceptconceptconcept
I understand you still use spring in 2019I understand you still use spring in 2019I understand you still use spring in 2019
Reduce risks / harmReduce risks / harmReduce risks / harm
We need time to adopt to new things /We need time to adopt to new things /We need time to adopt to new things / conceptconceptconcept
I understand you still use spring in 2019I understand you still use spring in 2019I understand you still use spring in 2019
Reduce risks / harmReduce risks / harmReduce risks / harm
Bill G icker image (Bill G icker image (Bill G icker image ( )))https://www. ickr.com/photos/billerr/1814657036https://www. ickr.com/photos/billerr/1814657036https://www. ickr.com/photos/billerr/1814657036
Bill G icker image (Bill G icker image (Bill G icker image ( )))
Baby stepsBaby stepsBaby steps
https://www. ickr.com/photos/billerr/1814657036https://www. ickr.com/photos/billerr/1814657036https://www. ickr.com/photos/billerr/1814657036
Spring 5 -> Spring Web ux is a huge step towards fpSpring 5 -> Spring Web ux is a huge step towards fpSpring 5 -> Spring Web ux is a huge step towards fp
Spring 5 -> Spring Web ux is a huge step towards fpSpring 5 -> Spring Web ux is a huge step towards fpSpring 5 -> Spring Web ux is a huge step towards fp
I have clean spring web ux based applications without beans !!!I have clean spring web ux based applications without beans !!!I have clean spring web ux based applications without beans !!!
Spring 5 -> Spring Web ux is a huge step towards fpSpring 5 -> Spring Web ux is a huge step towards fpSpring 5 -> Spring Web ux is a huge step towards fp
I have clean spring web ux based applications without beans !!!I have clean spring web ux based applications without beans !!!I have clean spring web ux based applications without beans !!!
Spring is not like a WAR (or Java EE)Spring is not like a WAR (or Java EE)Spring is not like a WAR (or Java EE)
Spring 5 -> Spring Web ux is a huge step towards fpSpring 5 -> Spring Web ux is a huge step towards fpSpring 5 -> Spring Web ux is a huge step towards fp
I have clean spring web ux based applications without beans !!!I have clean spring web ux based applications without beans !!!I have clean spring web ux based applications without beans !!!
Spring is not like a WAR (or Java EE)Spring is not like a WAR (or Java EE)Spring is not like a WAR (or Java EE)
It changesIt changesIt changes
Spring 5 -> Spring Web ux is a huge step towards fpSpring 5 -> Spring Web ux is a huge step towards fpSpring 5 -> Spring Web ux is a huge step towards fp
I have clean spring web ux based applications without beans !!!I have clean spring web ux based applications without beans !!!I have clean spring web ux based applications without beans !!!
Spring is not like a WAR (or Java EE)Spring is not like a WAR (or Java EE)Spring is not like a WAR (or Java EE)
It changesIt changesIt changes
maybe one day spring will not promote beans anymore?maybe one day spring will not promote beans anymore?maybe one day spring will not promote beans anymore?
Spring 5 -> Spring Web ux is a huge step towards fpSpring 5 -> Spring Web ux is a huge step towards fpSpring 5 -> Spring Web ux is a huge step towards fp
I have clean spring web ux based applications without beans !!!I have clean spring web ux based applications without beans !!!I have clean spring web ux based applications without beans !!!
Spring is not like a WAR (or Java EE)Spring is not like a WAR (or Java EE)Spring is not like a WAR (or Java EE)
It changesIt changesIt changes
maybe one day spring will not promote beans anymore?maybe one day spring will not promote beans anymore?maybe one day spring will not promote beans anymore?
They have stopped with XMLs some time agoThey have stopped with XMLs some time agoThey have stopped with XMLs some time ago
ENOUGHENOUGH
Thank youThank youThank you
@jarek000000@jarek000000@jarek000000
Sources:Sources:Sources:
Adam Warski 2017 - The Case against annotations
Tomer Gabel - Slaying sacred cows
From Spring Boot Apps to Functional Kotlin Nicholas Frankel
- plain java Pong server
-
https://sites.google.com/site/unclebobconsultingllc/blogs-by-robert-
martin/dependency-injection-inversion
https://www.youtube.com/watch?v=f6a78mCrSeE
https://github.com/javaFunAgain/ratpong
https://github.com/nee ect/nee

Contenu connexe

Similaire à Spring, CDI, Jakarta EE good parts

Voicecon - Mashups with Tropo.com
Voicecon - Mashups with Tropo.comVoicecon - Mashups with Tropo.com
Voicecon - Mashups with Tropo.com
Voxeo Corp
 

Similaire à Spring, CDI, Jakarta EE good parts (20)

Design and Evolution of cyber-dojo
Design and Evolution of cyber-dojoDesign and Evolution of cyber-dojo
Design and Evolution of cyber-dojo
 
Introduction to Programming in Go
Introduction to Programming in GoIntroduction to Programming in Go
Introduction to Programming in Go
 
Claudia Doppioslash - Time Travel for game development with Elm
Claudia Doppioslash - Time Travel for game development with ElmClaudia Doppioslash - Time Travel for game development with Elm
Claudia Doppioslash - Time Travel for game development with Elm
 
Paris Web - Javascript as a programming language
Paris Web - Javascript as a programming languageParis Web - Javascript as a programming language
Paris Web - Javascript as a programming language
 
Metasepi team meeting #16: Safety on ATS language + MCU
Metasepi team meeting #16: Safety on ATS language + MCUMetasepi team meeting #16: Safety on ATS language + MCU
Metasepi team meeting #16: Safety on ATS language + MCU
 
Functional IoT: Introduction
Functional IoT: IntroductionFunctional IoT: Introduction
Functional IoT: Introduction
 
Refactoring 2TheMax (con ReSharper)
Refactoring 2TheMax (con ReSharper)Refactoring 2TheMax (con ReSharper)
Refactoring 2TheMax (con ReSharper)
 
SFSCON23 - Denver Gingerich - How do you really do GPL enforcement
SFSCON23 - Denver Gingerich - How do you really do GPL enforcementSFSCON23 - Denver Gingerich - How do you really do GPL enforcement
SFSCON23 - Denver Gingerich - How do you really do GPL enforcement
 
Why we are still writing?
Why we are still writing?Why we are still writing?
Why we are still writing?
 
Dev secops opsec, devsec, devops ?
Dev secops opsec, devsec, devops ?Dev secops opsec, devsec, devops ?
Dev secops opsec, devsec, devops ?
 
BSides LA/PDX
BSides LA/PDXBSides LA/PDX
BSides LA/PDX
 
Machine vision and device integration with the Ruby programming language (2008)
Machine vision and device integration with the Ruby programming language (2008)Machine vision and device integration with the Ruby programming language (2008)
Machine vision and device integration with the Ruby programming language (2008)
 
Alex Fernández - Has anyone else seen your code? - Codemotion Berlin 2018
Alex Fernández - Has anyone else seen your code? - Codemotion Berlin 2018Alex Fernández - Has anyone else seen your code? - Codemotion Berlin 2018
Alex Fernández - Has anyone else seen your code? - Codemotion Berlin 2018
 
Types are eating the world
Types are eating the worldTypes are eating the world
Types are eating the world
 
Functional IoT: Programming Language and OS
Functional IoT: Programming Language and OSFunctional IoT: Programming Language and OS
Functional IoT: Programming Language and OS
 
Voicecon - Mashups with Tropo.com
Voicecon - Mashups with Tropo.comVoicecon - Mashups with Tropo.com
Voicecon - Mashups with Tropo.com
 
Ruby - The Hard Bits
Ruby - The Hard BitsRuby - The Hard Bits
Ruby - The Hard Bits
 
From Config Management Sucks to #cfgmgmtlove
From Config Management Sucks to #cfgmgmtlove From Config Management Sucks to #cfgmgmtlove
From Config Management Sucks to #cfgmgmtlove
 
A Backpack to go the Extra-Functional Mile (a hitched hike by the PROWESS pro...
A Backpack to go the Extra-Functional Mile (a hitched hike by the PROWESS pro...A Backpack to go the Extra-Functional Mile (a hitched hike by the PROWESS pro...
A Backpack to go the Extra-Functional Mile (a hitched hike by the PROWESS pro...
 
Cr java concept by vikas jagtap
Cr java  concept by vikas jagtapCr java  concept by vikas jagtap
Cr java concept by vikas jagtap
 

Plus de Jarek Ratajski

Lambda core
Lambda coreLambda core
Lambda core
Jarek Ratajski
 

Plus de Jarek Ratajski (17)

respect-estimates.pdf
respect-estimates.pdfrespect-estimates.pdf
respect-estimates.pdf
 
Pure Kotlin Devoxx PL 2021
Pure Kotlin Devoxx PL 2021Pure Kotlin Devoxx PL 2021
Pure Kotlin Devoxx PL 2021
 
Lambda hardcore
Lambda hardcoreLambda hardcore
Lambda hardcore
 
Pure kotlin
Pure kotlinPure kotlin
Pure kotlin
 
Transaction is a monad
Transaction is a  monadTransaction is a  monad
Transaction is a monad
 
Scala to assembly
Scala to assemblyScala to assembly
Scala to assembly
 
Eta lang Beauty And The Beast
Eta lang Beauty And The Beast Eta lang Beauty And The Beast
Eta lang Beauty And The Beast
 
Another programming language - jeszcze jeden język
Another programming language - jeszcze jeden językAnother programming language - jeszcze jeden język
Another programming language - jeszcze jeden język
 
Beauty and the beast - Haskell on JVM
Beauty and the beast  - Haskell on JVMBeauty and the beast  - Haskell on JVM
Beauty and the beast - Haskell on JVM
 
Fighting null with memes
Fighting null with memesFighting null with memes
Fighting null with memes
 
Eta
EtaEta
Eta
 
Geecon walking in CODE
Geecon walking in CODEGeecon walking in CODE
Geecon walking in CODE
 
Scalaworld lambda core hardcore
Scalaworld lambda core hardcoreScalaworld lambda core hardcore
Scalaworld lambda core hardcore
 
Lambda core
Lambda coreLambda core
Lambda core
 
[4 dev] lagom
[4 dev] lagom[4 dev] lagom
[4 dev] lagom
 
Jdd 2016 DROP DATABASE
Jdd 2016 DROP DATABASEJdd 2016 DROP DATABASE
Jdd 2016 DROP DATABASE
 
DROPDB Galactic story
DROPDB Galactic storyDROPDB Galactic story
DROPDB Galactic story
 

Dernier

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 

Dernier (20)

Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKSpring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
 
Cyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdfCyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdf
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdf
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 

Spring, CDI, Jakarta EE good parts

  • 1. SPRING, JAKARTA EE, CDISPRING, JAKARTA EE, CDI and otherand otherand other pathologiespathologiespathologies
  • 2. JAREK RATAJSKIJAREK RATAJSKI Software Developer, Wizard, AnarchitectSoftware Developer, Wizard, AnarchitectSoftware Developer, Wizard, Anarchitect at Engenius GmbHat Engenius GmbHat Engenius GmbH
  • 3. @ Engeniush GmbH@ Engeniush GmbH@ Engeniush GmbH Yes, we hireYes, we hireYes, we hire
  • 6. I WORK WITH JAVA EE SINCE ~2001I WORK WITH JAVA EE SINCE ~2001 WITH SPRING SINCE 2006WITH SPRING SINCE 2006 I remember EJB-OSS and huge xmls in Spring
  • 7. At the moment I amAt the moment I amAt the moment I am making my hands dirty in about 15 various Springmaking my hands dirty in about 15 various Springmaking my hands dirty in about 15 various Spring and Java EE projectsand Java EE projectsand Java EE projects
  • 8. I code for only few projects that are notI code for only few projects that are notI code for only few projects that are not SpringSpringSpring ororor Java EEJava EEJava EE basedbasedbased
  • 9. I code for only few projects that are notI code for only few projects that are notI code for only few projects that are not SpringSpringSpring ororor Java EEJava EEJava EE basedbasedbased including one very critical application (netty based)including one very critical application (netty based)including one very critical application (netty based)
  • 10. ⚠ I like xing production bugs:⚠ I like xing production bugs:⚠ I like xing production bugs:
  • 11. ⚠ I like xing production bugs:⚠ I like xing production bugs:⚠ I like xing production bugs: Concurrency, security, performance, heisenbugsConcurrency, security, performance, heisenbugsConcurrency, security, performance, heisenbugs
  • 12. As I have some Java EE, Spring experienceAs I have some Java EE, Spring experienceAs I have some Java EE, Spring experience
  • 13. As I have some Java EE, Spring experienceAs I have some Java EE, Spring experienceAs I have some Java EE, Spring experience I think,I think,I think,
  • 14. As I have some Java EE, Spring experienceAs I have some Java EE, Spring experienceAs I have some Java EE, Spring experience I think,I think,I think, they are doing too much harm to your code (architecture)they are doing too much harm to your code (architecture)they are doing too much harm to your code (architecture)
  • 15. As I have some Java EE, Spring experienceAs I have some Java EE, Spring experienceAs I have some Java EE, Spring experience I think,I think,I think, they are doing too much harm to your code (architecture)they are doing too much harm to your code (architecture)they are doing too much harm to your code (architecture) we have to do betterwe have to do betterwe have to do better
  • 16. STORY OFSTORY OF GO TOGO TO ((GOTOGOTO))
  • 17. GO TO STATEMENT CONSIDERED HARMFULGO TO STATEMENT CONSIDERED HARMFUL March 1968,March 1968,March 1968, Edsger W. DijkstraEdsger W. DijkstraEdsger W. Dijkstra
  • 18. E.D.E.D.E.D. For a number of years I have been familiar with theFor a number of years I have been familiar with theFor a number of years I have been familiar with the observation that the quality of programmers is aobservation that the quality of programmers is aobservation that the quality of programmers is a decreasing function of the density of go todecreasing function of the density of go todecreasing function of the density of go to statements in the programs they produce. Morestatements in the programs they produce. Morestatements in the programs they produce. More recently I discovered why the use of the go torecently I discovered why the use of the go torecently I discovered why the use of the go to statement has such disastrous e ects, and I becamestatement has such disastrous e ects, and I becamestatement has such disastrous e ects, and I became convinced that the go to statement should beconvinced that the go to statement should beconvinced that the go to statement should be abolished from all "higher level" programmingabolished from all "higher level" programmingabolished from all "higher level" programming languages (i.e. everything except, perhaps, plainlanguages (i.e. everything except, perhaps, plainlanguages (i.e. everything except, perhaps, plain machine code). At that time I did not attach toomachine code). At that time I did not attach toomachine code). At that time I did not attach too much importance to this discovery; I now submit mymuch importance to this discovery; I now submit mymuch importance to this discovery; I now submit my considerations for publication because in veryconsiderations for publication because in veryconsiderations for publication because in very recent discussions in which the subject turned up, Irecent discussions in which the subject turned up, Irecent discussions in which the subject turned up, I have been urged to do so.have been urged to do so.have been urged to do so.
  • 19. GOT0 CONSIDERED HARMFUL - CONSIDERED HARMFULGOT0 CONSIDERED HARMFUL - CONSIDERED HARMFUL March 1987, Frank RubinMarch 1987, Frank RubinMarch 1987, Frank Rubin
  • 20. F.R.F.R.F.R. GOTO-less programs are harder and costlier toGOTO-less programs are harder and costlier toGOTO-less programs are harder and costlier to create, test, and modify.create, test, and modify.create, test, and modify.
  • 21. F.R.F.R.F.R. AsAsAs I introduce GOTOs to untangleI introduce GOTOs to untangleI introduce GOTOs to untangle each deeplyeach deeplyeach deeply nested mess of code,nested mess of code,nested mess of code, I have found that the numberI have found that the numberI have found that the number of lines of code often drops byof lines of code often drops byof lines of code often drops by 20-25 percent,20-25 percent,20-25 percent,
  • 22. F.R.F.R.F.R. I am aware that some awful programs have beenI am aware that some awful programs have beenI am aware that some awful programs have been written usingwritten usingwritten using GOTOs. This is often the fault ofGOTOs. This is often the fault ofGOTOs. This is often the fault of thethethe language (because it lackslanguage (because it lackslanguage (because it lacks other constructs), or theother constructs), or theother constructs), or the text editor (because it lacks a blocktext editor (because it lacks a blocktext editor (because it lacks a block move). With amove). With amove). With a proper languageproper languageproper language and editor, and adequateand editor, and adequateand editor, and adequate instruction in the use of GOTO, thisinstruction in the use of GOTO, thisinstruction in the use of GOTO, this should not be ashould not be ashould not be a consideration.consideration.consideration.
  • 23. somesomesome C# .NetC# .NetC# .Net code presented to proove howcode presented to proove howcode presented to proove how COOLCOOLCOOL goto is (at polishgoto is (at polishgoto is (at polish 4programmers message board)4programmers message board)4programmers message board) private static bool TryParseSByteD(ReadOnlySpan<byte> source, out sbyte value, out int bytesConsumed) { if (source.Length < 1) goto FalseExit; int sign = 1; int index = 0; int num = source[index]; if (num == '-') { sign = -1; index++; if ((uint)index >= (uint)source.Length) goto FalseExit; num = source[index]; } else if (num == '+') { index++; if ((uint)index >= (uint)source.Length) goto FalseExit; num = source[index]; } int answer = 0; if (ParserHelpers.IsDigit(num)) { if (num == '0') { do { index++; if ((uint)index >= (uint)source.Length) goto Done; num = source[index]; } while (num == '0'); if (!ParserHelpers.IsDigit(num)) goto Done; } answer = num - '0'; index++; if ((uint)index >= (uint)source.Length) goto Done; num = source[index]; if (!ParserHelpers.IsDigit(num)) goto Done; index++; answer = 10 * answer + num - '0'; // Potential overflow if ((uint)index >= (uint)source.Length) goto Done; num = source[index];
  • 24. ON A SOMEWHAT DISAPPOINTING CORRESPONDENCEON A SOMEWHAT DISAPPOINTING CORRESPONDENCE May 1987, Edsger W. DijkstraMay 1987, Edsger W. DijkstraMay 1987, Edsger W. Dijkstra
  • 25. E.D.E.D.E.D. By my standards, a competent professionalBy my standards, a competent professionalBy my standards, a competent professional programmer in 1987programmer in 1987programmer in 1987 should recognize that Rubin’s problem asks to be solved by a nested application of the same algorithm; should know the theorem of “The bounded linear search”; should be able to derive that theorem and its proof; should not hesitate to use it; should not waste his time in pointing out that the boolean variable d is super uous; should keep his repetitions simple and disentangled; etc. . .
  • 26. It is typically possible to show how greatIt is typically possible to show how greatIt is typically possible to show how great GO TOGO TOGO TO is,is,is, on a small selectedon a small selectedon a small selected piece of codepiece of codepiece of code it is performantit is performantit is performant write nowwrite nowwrite now - jump anywhere- jump anywhere- jump anywhere
  • 28.
  • 29. BrokenBrokenBroken local reasoninglocal reasoninglocal reasoning
  • 30. BrokenBrokenBroken local reasoninglocal reasoninglocal reasoning how much code do you have to read when something does not workhow much code do you have to read when something does not workhow much code do you have to read when something does not work
  • 31. MAINSTREAM INDUSTRY STOPPED USINGMAINSTREAM INDUSTRY STOPPED USING "GOTO""GOTO" DECADESDECADES AGOAGO Costs (risks) are greater thanCosts (risks) are greater thanCosts (risks) are greater than pro tspro tspro ts
  • 34. 10:10: BeansBeans (AS YOU KNOW) ARE(AS YOU KNOW) ARE "GOTOs""GOTOs" OF JAVAOF JAVA
  • 35. WHAT IS AWHAT IS A BeanBean??
  • 36. Forget about classicForget about classicForget about classic JavaBeansJavaBeansJavaBeans
  • 37. Forget about classicForget about classicForget about classic JavaBeansJavaBeansJavaBeans This is closed topic,This is closed topic,This is closed topic, we don't gowe don't gowe don't go there anymorethere anymorethere anymore
  • 38. SPRING BEANS, JAVA EE BEANS, CDI BEANS, JSF,SPRING BEANS, JAVA EE BEANS, CDI BEANS, JSF, JPA...JPA...
  • 39. BEAN == MUTILATED, CRIPPLED CLASS(OBJECT) IN JAVABEAN == MUTILATED, CRIPPLED CLASS(OBJECT) IN JAVA
  • 40. BEAN == MUTILATED, CRIPPLED CLASS(OBJECT) IN JAVABEAN == MUTILATED, CRIPPLED CLASS(OBJECT) IN JAVA Looks like normal object, but does not behave (like) normalLooks like normal object, but does not behave (like) normalLooks like normal object, but does not behave (like) normal
  • 41. BEAN == MUTILATED, CRIPPLED CLASS(OBJECT) IN JAVABEAN == MUTILATED, CRIPPLED CLASS(OBJECT) IN JAVA Looks like normal object, but does not behave (like) normalLooks like normal object, but does not behave (like) normalLooks like normal object, but does not behave (like) normal
  • 42. BEAN == MUTILATED, CRIPPLED CLASS(OBJECT) IN JAVABEAN == MUTILATED, CRIPPLED CLASS(OBJECT) IN JAVA Looks like normal object, but does not behave (like) normalLooks like normal object, but does not behave (like) normalLooks like normal object, but does not behave (like) normal Not instantiated by new
  • 43. BEAN == MUTILATED, CRIPPLED CLASS(OBJECT) IN JAVABEAN == MUTILATED, CRIPPLED CLASS(OBJECT) IN JAVA Looks like normal object, but does not behave (like) normalLooks like normal object, but does not behave (like) normalLooks like normal object, but does not behave (like) normal Not instantiated by new
  • 44. BEAN == MUTILATED, CRIPPLED CLASS(OBJECT) IN JAVABEAN == MUTILATED, CRIPPLED CLASS(OBJECT) IN JAVA Looks like normal object, but does not behave (like) normalLooks like normal object, but does not behave (like) normalLooks like normal object, but does not behave (like) normal Not instantiated by new there are special rules, limitations, conventions on use
  • 46. 20: DISASTER NO. 120: DISASTER NO. 1
  • 48. dependency injectiondependency injectiondependency injection - what is a DI?- what is a DI?- what is a DI?
  • 49. WikipediaWikipediaWikipedia In software engineering, dependency injection is aIn software engineering, dependency injection is aIn software engineering, dependency injection is a technique whereby one object supplies thetechnique whereby one object supplies thetechnique whereby one object supplies the dependencies of another object. A "dependency" isdependencies of another object. A "dependency" isdependencies of another object. A "dependency" is an object that can be used, for example a service.an object that can be used, for example a service.an object that can be used, for example a service. Instead of a client specifying which service it willInstead of a client specifying which service it willInstead of a client specifying which service it will use, something tells the client what service to use.use, something tells the client what service to use.use, something tells the client what service to use. The "injection" refers to the passing of a dependencyThe "injection" refers to the passing of a dependencyThe "injection" refers to the passing of a dependency (a service) into the object (a client) that would use it.(a service) into the object (a client) that would use it.(a service) into the object (a client) that would use it. The service is made part of the client's state.[1]The service is made part of the client's state.[1]The service is made part of the client's state.[1] Passing the service to the client, rather thanPassing the service to the client, rather thanPassing the service to the client, rather than allowing a client to build or nd the service, is theallowing a client to build or nd the service, is theallowing a client to build or nd the service, is the fundamental requirement of the pattern.fundamental requirement of the pattern.fundamental requirement of the pattern.
  • 50. Passing the service to the client, rather thanPassing the service to the client, rather thanPassing the service to the client, rather than allowing a client to build or nd the service, is theallowing a client to build or nd the service, is theallowing a client to build or nd the service, is the fundamental requirement of the pattern.fundamental requirement of the pattern.fundamental requirement of the pattern.
  • 51. Do we have aDo we have aDo we have a dependency injectiondependency injectiondependency injection here?here?here? class MyService { private final DbRepo db; public MyService() { this.db = new DbRepo("jdbc://url") } }
  • 52. Do we have aDo we have aDo we have a dependency injectiondependency injectiondependency injection here?here?here? class MyService { private final DbRepo db; public MyService(DbRepo db) { this.db = db; } } MyService serviceProvider() { var db = new DbRepo("jdbc://url") return MyService(db) }
  • 53. https://sites.google.com/site/unclebobconsultingllc/blogs-by-robert-https://sites.google.com/site/unclebobconsultingllc/blogs-by-robert-https://sites.google.com/site/unclebobconsultingllc/blogs-by-robert- martin/dependency-injection-inversionmartin/dependency-injection-inversionmartin/dependency-injection-inversion Dependency Injection doesn’t require a framework;Dependency Injection doesn’t require a framework;Dependency Injection doesn’t require a framework; it just requires that you invert your dependenciesit just requires that you invert your dependenciesit just requires that you invert your dependencies and then construct and pass your arguments toand then construct and pass your arguments toand then construct and pass your arguments to deeper layers.deeper layers.deeper layers.
  • 54. Framework (IoC container) lets youFramework (IoC container) lets youFramework (IoC container) lets you injectinjectinject at aat aat a small costsmall costsmall cost
  • 55. Framework (IoC container) lets youFramework (IoC container) lets youFramework (IoC container) lets you injectinjectinject at aat aat a small costsmall costsmall cost
  • 56. Framework (IoC container) lets youFramework (IoC container) lets youFramework (IoC container) lets you injectinjectinject at aat aat a small costsmall costsmall cost It is in fact technical debt - you will pay laterIt is in fact technical debt - you will pay laterIt is in fact technical debt - you will pay later
  • 57. Typical Spring (DI) application architectureTypical Spring (DI) application architectureTypical Spring (DI) application architecture (simpli ed)(simpli ed)(simpli ed)
  • 58.
  • 59. Repository in Controller - no problemRepository in Controller - no problemRepository in Controller - no problem
  • 60. Repository in Controller - no problemRepository in Controller - no problemRepository in Controller - no problem HttpRequest in Persistence layer - no problemHttpRequest in Persistence layer - no problemHttpRequest in Persistence layer - no problem
  • 61. Repository in Controller - no problemRepository in Controller - no problemRepository in Controller - no problem HttpRequest in Persistence layer - no problemHttpRequest in Persistence layer - no problemHttpRequest in Persistence layer - no problem Injecting anything anywhere - no problemInjecting anything anywhere - no problemInjecting anything anywhere - no problem
  • 62. Repository in Controller - no problemRepository in Controller - no problemRepository in Controller - no problem HttpRequest in Persistence layer - no problemHttpRequest in Persistence layer - no problemHttpRequest in Persistence layer - no problem Injecting anything anywhere - no problemInjecting anything anywhere - no problemInjecting anything anywhere - no problem Bean transferred diseases - gratisBean transferred diseases - gratisBean transferred diseases - gratis
  • 63. Beans just pretend they are not infamousBeans just pretend they are not infamousBeans just pretend they are not infamous SingletonSingletonSingletonsss
  • 64. Only bad developers do thisOnly bad developers do thisOnly bad developers do this
  • 65. Only bad developers do thisOnly bad developers do thisOnly bad developers do this
  • 66. Only bad developers do thisOnly bad developers do thisOnly bad developers do this oh, really?oh, really?oh, really?
  • 67. It is likeIt is likeIt is like GO TOGO TOGO TO
  • 68. Sooner or later someone will make a shortcut an hour before DEMOSooner or later someone will make a shortcut an hour before DEMOSooner or later someone will make a shortcut an hour before DEMO An it will stay like that -An it will stay like that -An it will stay like that - foreverforeverforever Because, the most important things in agile are:Because, the most important things in agile are:Because, the most important things in agile are:
  • 69. Sooner or later someone will make a shortcut an hour before DEMOSooner or later someone will make a shortcut an hour before DEMOSooner or later someone will make a shortcut an hour before DEMO An it will stay like that -An it will stay like that -An it will stay like that - foreverforeverforever Because, the most important things in agile are:Because, the most important things in agile are:Because, the most important things in agile are: VelocityVelocityVelocity and niceand niceand nice burndown chartsburndown chartsburndown charts
  • 70.
  • 71. LOBOLOBO Level of Beans obscurityLevel of Beans obscurityLevel of Beans obscurity (same for Jakarta EE -(same for Jakarta EE -(same for Jakarta EE - CDICDICDI @Inject@Inject@Inject, EJB, EJB, EJB @EJB@EJB@EJB ...)...)...)
  • 72. It is evenIt is evenIt is even pro containerspro containerspro containers argument !argument !argument ! Would you write all those hundreds of injectionsWould you write all those hundreds of injectionsWould you write all those hundreds of injections manually?manually?manually?
  • 74. Step 0Step 0Step 0 class A { @Autowired Xx; @Autowired Y y; @AUtowired Z z; }
  • 75. Step 1Step 1Step 1 ((( ))) class A { final X x; final Y y; final Z z; @Autowired A(X x, Y y, Z z) { this.x =x; this.y = y; this.z = z; } } http://olivergierke.de/2013/11/why- eld-injection-is-evil/http://olivergierke.de/2013/11/why- eld-injection-is-evil/http://olivergierke.de/2013/11/why- eld-injection-is-evil/
  • 76. Step 2Step 2Step 2 class A { final X x; final Y y; final Z z; //@Autowired A(X x, Y y, Z z) { this.x =x; this.y = y; this.z = z; } }
  • 77. BACK TO CODING SCHOOL:BACK TO CODING SCHOOL:
  • 78. BACK TO CODING SCHOOL:BACK TO CODING SCHOOL: If code is repeated - extract it to functionIf code is repeated - extract it to functionIf code is repeated - extract it to function
  • 79. BACK TO CODING SCHOOL:BACK TO CODING SCHOOL: If code is repeated - extract it to functionIf code is repeated - extract it to functionIf code is repeated - extract it to function Sections of repeatingSections of repeatingSections of repeating newnewnew can be as well extractedcan be as well extractedcan be as well extracted
  • 80. BACK TO CODING SCHOOL:BACK TO CODING SCHOOL: If code is repeated - extract it to functionIf code is repeated - extract it to functionIf code is repeated - extract it to function Sections of repeatingSections of repeatingSections of repeating newnewnew can be as well extractedcan be as well extractedcan be as well extracted Use factories / providersUse factories / providersUse factories / providers
  • 81. BACK TO CODING SCHOOL:BACK TO CODING SCHOOL: If code is repeated - extract it to functionIf code is repeated - extract it to functionIf code is repeated - extract it to function Sections of repeatingSections of repeatingSections of repeating newnewnew can be as well extractedcan be as well extractedcan be as well extracted Use factories / providersUse factories / providersUse factories / providers Too many arguements in constructor? Split a class in two (or three) (!)Too many arguements in constructor? Split a class in two (or three) (!)Too many arguements in constructor? Split a class in two (or three) (!)
  • 82. PLENTY OF "BEANS" HAVE EXACTLY ONEPLENTY OF "BEANS" HAVE EXACTLY ONE IMPLEMENTATIONIMPLEMENTATION
  • 83. PLENTY OF "BEANS" HAVE EXACTLY ONEPLENTY OF "BEANS" HAVE EXACTLY ONE IMPLEMENTATIONIMPLEMENTATION Services, Controllers...Services, Controllers...Services, Controllers...
  • 84. PLENTY OF "BEANS" HAVE EXACTLY ONEPLENTY OF "BEANS" HAVE EXACTLY ONE IMPLEMENTATIONIMPLEMENTATION Services, Controllers...Services, Controllers...Services, Controllers... You don't need to make everything injectableYou don't need to make everything injectableYou don't need to make everything injectable
  • 85. EXAMPLE (IN KOTLIN + VAVR)EXAMPLE (IN KOTLIN + VAVR) data class StonesModule( private val seq: DbSequence = DbSequence(), val stoneRepo: Lazy<StoneRepo> = Lazy.of { StoneRepo(seq) }, val stoneService: Lazy<StoneService> = Lazy.of {StoneService val stoneRest: Lazy<StoneRest> = Lazy.of {StoneRest(stoneSer ) //this is Kotlin uber constructor // somewhere else val myModule = StoneRepo( stoneRepo = Lazy.of{MyRepo()}) val service = myModule.stoneService.get()
  • 86. "MANUAL" DI VS FRAMEWORK"MANUAL" DI VS FRAMEWORK Manual DI vs container IoC small pain every day <--> no problem for months - the disaster tree like structure <--> ball of mud (messy cake) 3 - 6 deps per class <--> 5 - 18 deps per class (LOBO)
  • 88. THERE ARE BEANS WORSE THAN SINGLETONS....THERE ARE BEANS WORSE THAN SINGLETONS....
  • 89. THERE ARE BEANS WORSE THAN SINGLETONS....THERE ARE BEANS WORSE THAN SINGLETONS.... Request scoped
  • 90. THERE ARE BEANS WORSE THAN SINGLETONS....THERE ARE BEANS WORSE THAN SINGLETONS.... Request scoped Session scoped
  • 91. THERE ARE BEANS WORSE THAN SINGLETONS....THERE ARE BEANS WORSE THAN SINGLETONS.... Request scoped Session scoped ThreadLocal based
  • 92. THERE ARE BEANS WORSE THAN SINGLETONS....THERE ARE BEANS WORSE THAN SINGLETONS.... Request scoped Session scoped ThreadLocal based Those are in factThose are in factThose are in fact global variablesglobal variablesglobal variables
  • 93. private C method1( A a, B b) { //uses a, b, and this. fields this.serviceX.method2(a); //does not use `b` this.serviceY.method3(b); //method does not use `a` }
  • 94. @Component @Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS) class TrollService { public A getA() { return a; } public void setA(A a) { this.a = a; } private A a; } @Service public class ServiceX { @Autowired private TrollService trollService; void method2(A a) { trollService.setA(a); } }
  • 95. In spring based projects this isIn spring based projects this isIn spring based projects this is normalnormalnormal (especially in Spring batch)(especially in Spring batch)(especially in Spring batch)
  • 96. BrokenBrokenBroken Local reasoningLocal reasoningLocal reasoning
  • 97. OUTCOME:OUTCOME: Many of small, reasonable changesMany of small, reasonable changesMany of small, reasonable changes can break your systemcan break your systemcan break your system
  • 98. OUTCOME:OUTCOME: Many of small, reasonable changesMany of small, reasonable changesMany of small, reasonable changes can break your systemcan break your systemcan break your system and tests are still green (because they test only mocks)and tests are still green (because they test only mocks)and tests are still green (because they test only mocks)
  • 99. OUTCOME:OUTCOME: Many of small, reasonable changesMany of small, reasonable changesMany of small, reasonable changes can break your systemcan break your systemcan break your system and tests are still green (because they test only mocks)and tests are still green (because they test only mocks)and tests are still green (because they test only mocks) Sleep well, all yourSleep well, all yourSleep well, all your tests are greentests are greentests are green
  • 100.
  • 101. Slaying Sacred Cows: Deconstructing Dependency InjectionSlaying Sacred Cows: Deconstructing Dependency InjectionSlaying Sacred Cows: Deconstructing Dependency Injection Tomer GabelTomer GabelTomer Gabel
  • 103. 2005:2005: DISASTER NO. 2DISASTER NO. 2
  • 106. WhenWhenWhen @Transactional@Transactional@Transactional does not work?does not work?does not work?
  • 107. WhenWhenWhen @Transactional@Transactional@Transactional does not work?does not work?does not work? private method
  • 108. WhenWhenWhen @Transactional@Transactional@Transactional does not work?does not work?does not work? private method public, but this.call(...)
  • 109. WhenWhenWhen @Transactional@Transactional@Transactional does not work?does not work?does not work? private method public, but this.call(...) object instantiated with new
  • 110. WhenWhenWhen @Transactional@Transactional@Transactional does not work?does not work?does not work? private method public, but this.call(...) object instantiated with new kotlin nal class/method (*)
  • 111. WhenWhenWhen @Transactional@Transactional@Transactional does not work?does not work?does not work? private method public, but this.call(...) object instantiated with new kotlin nal class/method (*) called in other thread (parallelStream(), future)
  • 112. WhenWhenWhen @Transactional@Transactional@Transactional does not work?does not work?does not work? private method public, but this.call(...) object instantiated with new kotlin nal class/method (*) called in other thread (parallelStream(), future) troll aspekt (@Trollsactional)
  • 113. WhenWhenWhen @Transactional@Transactional@Transactional does not work?does not work?does not work? private method public, but this.call(...) object instantiated with new kotlin nal class/method (*) called in other thread (parallelStream(), future) troll aspekt (@Trollsactional) missing jar on server
  • 114. ADDADD JPA MAGIC ON TOP OF THATJPA MAGIC ON TOP OF THAT other magic Beans managed detached dirty check proxy
  • 115. ADDADD TRANSACTION ISOLATION LEVEL ASSOCIATED ISSUESTRANSACTION ISOLATION LEVEL ASSOCIATED ISSUES A.C.I.D.A.C.I.D.
  • 116. Spring withSpring withSpring with @Transactional@Transactional@Transactional andandand JPA, and Database all togetherJPA, and Database all togetherJPA, and Database all together
  • 117. IfIfIf @Transactional@Transactional@Transactional does not work - where do you put a breakpoint?does not work - where do you put a breakpoint?does not work - where do you put a breakpoint?
  • 118. All aspects induce similar problems:All aspects induce similar problems:All aspects induce similar problems: @Secured @RolesAllowed @Cacheable @Lock ...
  • 119. All aspects induce similar problems:All aspects induce similar problems:All aspects induce similar problems: @Secured @RolesAllowed @Cacheable @Lock ... Can your company accept that those aspects may beCan your company accept that those aspects may beCan your company accept that those aspects may be not active onnot active onnot active on productionproductionproduction???
  • 120. All aspects induce similar problems:All aspects induce similar problems:All aspects induce similar problems: @Secured @RolesAllowed @Cacheable @Lock ... Can your company accept that those aspects may beCan your company accept that those aspects may beCan your company accept that those aspects may be not active onnot active onnot active on productionproductionproduction??? after small refactoring ?after small refactoring ?after small refactoring ?
  • 121. All aspects induce similar problems:All aspects induce similar problems:All aspects induce similar problems: @Secured @RolesAllowed @Cacheable @Lock ... Can your company accept that those aspects may beCan your company accept that those aspects may beCan your company accept that those aspects may be not active onnot active onnot active on productionproductionproduction??? after small refactoring ?after small refactoring ?after small refactoring ?
  • 122. Those are just NOTThose are just NOTThose are just NOT edge casesedge casesedge cases
  • 123.
  • 124. It happens more often than you thinkIt happens more often than you thinkIt happens more often than you think
  • 125. Some of the problems (like async) are solved by another set ofSome of the problems (like async) are solved by another set ofSome of the problems (like async) are solved by another set of annotationsannotationsannotations @AspectJ, @PostConstruct, @EnableAsync, @EnableScheduling, @NoRepositoryBean
  • 126. Bean based development - a gentle introductionBean based development - a gentle introductionBean based development - a gentle introduction
  • 127.
  • 128.
  • 129. MAGIC IN CODEMAGIC IN CODE
  • 130. MAGIC IN CODEMAGIC IN CODE actually false (useless) de nitionactually false (useless) de nitionactually false (useless) de nition
  • 131. MAGIC IN CODEMAGIC IN CODE actually false (useless) de nitionactually false (useless) de nitionactually false (useless) de nition THINGS, WE DO NOTTHINGS, WE DO NOT UNDERSTANDUNDERSTAND
  • 132. MAGIC INMAGIC IN CODECODE
  • 133. MAGIC INMAGIC IN CODECODE practical de nition (v2.0practical de nition (v2.0practical de nition (v2.0 stable)stable)stable)
  • 134. MAGIC INMAGIC IN CODECODE practical de nition (v2.0practical de nition (v2.0practical de nition (v2.0 stable)stable)stable) THINGS,THINGS, THAT DO NOTTHAT DO NOT COMPOSE SAFELYCOMPOSE SAFELY
  • 135. John De GoesJohn De GoesJohn De Goes
  • 136. John de Goes (again)John de Goes (again)John de Goes (again) Magic is a feature with non-compositionalMagic is a feature with non-compositionalMagic is a feature with non-compositional semantics that succeeds in making thesemantics that succeeds in making thesemantics that succeeds in making the commoncommoncommon case easy, at the cost of making the uncommoncase easy, at the cost of making the uncommoncase easy, at the cost of making the uncommon cases surprising, impossible, or ridiculouslycases surprising, impossible, or ridiculouslycases surprising, impossible, or ridiculously complex.complex.complex.
  • 137. MAGICMAGIC Dynamic proxy Thread local Runtime re ection Instrumentation bytecode manipulation Stringly typed annotations
  • 141. Is retry inside transaction or transaction inside retry?Is retry inside transaction or transaction inside retry?Is retry inside transaction or transaction inside retry? @Transactional @Retryable void myMethod () { }
  • 142. Is retry inside transaction or transaction inside retry?Is retry inside transaction or transaction inside retry?Is retry inside transaction or transaction inside retry? cache?, security? -> have funcache?, security? -> have funcache?, security? -> have fun @Transactional @Retryable void myMethod () { }
  • 143. (hidden) cost of beans magic:(hidden) cost of beans magic:(hidden) cost of beans magic: Heisenbugs Stopped development Unrealistic tests ( no aspects covered) Slow tests (with aspects) Overmocking (aka Mocksturbation, ...sorry) Fear of refactoring classpath / classloader disasters (on application servers) problem with new java versions (not in Spring) ugly architecture with shortcuts
  • 144. SPRING IS NOT SIMPLESPRING IS NOT SIMPLE
  • 146. 666: MY TOP 3 - MOST666: MY TOP 3 - MOST DANGEROUS (MAGIC) TOOLSDANGEROUS (MAGIC) TOOLS
  • 147. 3. JPA3. JPA void method(User user) { user.setName("Irek"); //will be saved? user.getGroups().forEach(...); //will work? }
  • 148. 3. JPA3. JPA Depends: isDepends: isDepends: is bean managed (tracked in JPA session),bean managed (tracked in JPA session),bean managed (tracked in JPA session), void method(User user) { user.setName("Irek"); //will be saved? user.getGroups().forEach(...); //will work? }
  • 149. 3. JPA3. JPA Depends: isDepends: isDepends: is bean managed (tracked in JPA session),bean managed (tracked in JPA session),bean managed (tracked in JPA session), waswaswas getGroupsgetGroupsgetGroups called before?called before?called before? void method(User user) { user.setName("Irek"); //will be saved? user.getGroups().forEach(...); //will work? }
  • 150. JPA Totally breaksJPA Totally breaksJPA Totally breaks local reasoninglocal reasoninglocal reasoning
  • 151. People generally know SQLPeople generally know SQLPeople generally know SQL ThenThenThen spend hours translating SQL to JPAspend hours translating SQL to JPAspend hours translating SQL to JPA
  • 152. People generally know SQLPeople generally know SQLPeople generally know SQL ThenThenThen spend hours translating SQL to JPAspend hours translating SQL to JPAspend hours translating SQL to JPA And they useAnd they useAnd they use .save().save().save() for updatesfor updatesfor updates
  • 153. People generally know SQLPeople generally know SQLPeople generally know SQL ThenThenThen spend hours translating SQL to JPAspend hours translating SQL to JPAspend hours translating SQL to JPA And they useAnd they useAnd they use .save().save().save() for updatesfor updatesfor updates Which means probably - they have no clueWhich means probably - they have no clueWhich means probably - they have no clue
  • 154. 2. APPLICATION SERVERS2. APPLICATION SERVERS Websphere, JBoss, Tomcat Classpath problems vendor lock-in / java version lock-in lost in debug testability(*) way worse than in Spring (I am looking at you Arquillian)
  • 155. 1. JSF1. JSF Maybe not the worst web framework ever doneMaybe not the worst web framework ever doneMaybe not the worst web framework ever done ButButBut it sets the bar pretty highit sets the bar pretty highit sets the bar pretty high (for evil ones)(for evil ones)(for evil ones) SessionScope hell disaster in phases resource consumption (Memory) funny integration problems with other Beans
  • 156. HOW ALL THAT HAPPENED?HOW ALL THAT HAPPENED?
  • 157. Long time ago...Long time ago...Long time ago...
  • 158. JAVA EE (1.X, 2.X)JAVA EE (1.X, 2.X) Enterprise Java Bean - remote objects (better CORBA/RMI) No one simply crates remote objects by new Java EE/EJB - RMI on steroids distributed transactions 2 phase commit security in remote calls
  • 159. SERVLETSSERVLETS Classpath scan instantiation by a container default constructor
  • 160. How can you test it?How can you test it?How can you test it? public class HelloWorld extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResp throws ServletException, IOException { PrintWriter out = response.getWriter(); out.println("<h1>" + message + "</h1>"); } }
  • 161. ONCE WE HAD NO GENERICS (BEFORE JAVA 5)ONCE WE HAD NO GENERICS (BEFORE JAVA 5) //java 5 interface Provider<T> { T getService(); } //java 1.4 interface Provider { Object getService(); }
  • 162. NO LAMBDAS (BEFORENO LAMBDAS (BEFORE JAVA 8)JAVA 8) "Aspect" done in a proper way"Aspect" done in a proper way"Aspect" done in a proper way void <R> R doInTranasction( Funtion<DBTRansaction, R> code) { var trx = b.beginTransaction(); try { var result = code.apply(trx); trx.commit(); return result; } catch (...) { trx.rollback(); throw ... } }
  • 163. AT THE TIME OF JAVA 1.4AT THE TIME OF JAVA 1.4 Spring was e cient way of creating web applicationsSpring was e cient way of creating web applicationsSpring was e cient way of creating web applications
  • 164. Up to java 7 there were not that many sensible alternativesUp to java 7 there were not that many sensible alternativesUp to java 7 there were not that many sensible alternatives
  • 165. From javaFrom javaFrom java 8 on8 on8 on
  • 166. From javaFrom javaFrom java 8 on8 on8 on We can use lambdas to provide similar functionality as aspects in aWe can use lambdas to provide similar functionality as aspects in aWe can use lambdas to provide similar functionality as aspects in a compile safe waycompile safe waycompile safe way - without magic- without magic- without magic
  • 167. From javaFrom javaFrom java 8 on8 on8 on We can use lambdas to provide similar functionality as aspects in aWe can use lambdas to provide similar functionality as aspects in aWe can use lambdas to provide similar functionality as aspects in a compile safe waycompile safe waycompile safe way - without magic- without magic- without magic We have mature alternatives to servlets (netty, ratpack, sparkjava,We have mature alternatives to servlets (netty, ratpack, sparkjava,We have mature alternatives to servlets (netty, ratpack, sparkjava, spring web ux)spring web ux)spring web ux)
  • 168. PSYCHOLOGICAL ASPECTSPSYCHOLOGICAL ASPECTS everybody Java EE / Spring magic is great (it worked again, miracle, wow) Stockholm syndrome developers ignore costs (risks)
  • 170. STEP 1STEP 1 Drop application serversDrop application serversDrop application servers Make Jar not War (Make Jar not War (Make Jar not War ( SpringBootSpringBootSpringBoot is good for a start)is good for a start)is good for a start) use Kotlinuse Kotlinuse Kotlin use vavr.iouse vavr.iouse vavr.io
  • 171. STEP 2STEP 2 Hold your BeansHold your BeansHold your Beans Use Beans where really neededUse Beans where really neededUse Beans where really needed (example -> only(example -> only(example -> only Jax-RS annotations andJax-RS annotations andJax-RS annotations and @Controllers@Controllers@Controllers))) Only constructors for DIOnly constructors for DIOnly constructors for DI
  • 172. STEP 3STEP 3 (fun starts)(fun starts)(fun starts) Drop JPADrop JPADrop JPA Try:Try:Try: JOOQ, QueryDSL and alternativesJOOQ, QueryDSL and alternativesJOOQ, QueryDSL and alternatives
  • 173. STEP 4STEP 4 Go functionsGo functionsGo functions
  • 174. Spring WebFlux (withoutSpring WebFlux (withoutSpring WebFlux (without beans)beans)beans) class WisniaServer { fun start() { val route = router { GET("/hello", handle(::printHello)) GET("/helloUser", secure(handle(::printlHelloForUser))) } val httpHandler = RouterFunctions.toHttpHandler(route) val adapter = ReactorHttpHandlerAdapter(httpHandler) val server = HttpServer .create() .host("localhost") .port(8080) .handle(adapter) .bindNow() println("press enter") readLine() server.disposeNow() } }
  • 175. This line:This line:This line: secure(handle(::printlHelloForUser)))
  • 176. This all works nicelyThis all works nicelyThis all works nicely in:in:in:
  • 177. This all works nicelyThis all works nicelyThis all works nicely in:in:in: SPRINGSPRING
  • 178. This all works nicelyThis all works nicelyThis all works nicely in:in:in: SPRINGSPRING SPRING WEBFLUXSPRING WEBFLUX
  • 179. This all works nicelyThis all works nicelyThis all works nicely in:in:in: SPRINGSPRING SPRING WEBFLUXSPRING WEBFLUX FullyFullyFully functionalfunctionalfunctional syntax, no beans, no annotations, no aspects neededsyntax, no beans, no annotations, no aspects neededsyntax, no beans, no annotations, no aspects needed
  • 180. No classpath scanning -> SpringWeb ux starts in 200msNo classpath scanning -> SpringWeb ux starts in 200msNo classpath scanning -> SpringWeb ux starts in 200ms Ratpack (alternative) starts in 10msRatpack (alternative) starts in 10msRatpack (alternative) starts in 10ms
  • 181. Testing ofTesting ofTesting of functionalfunctionalfunctional applications is fast and easyapplications is fast and easyapplications is fast and easy var app = Application(withMyTestDB).start(); var result = app.myApiCall(); assertEquals(expectedResult, result);
  • 182. STEP 5 (REAL FUN)STEP 5 (REAL FUN) Go monadsGo monadsGo monads Transaction is a monadTransaction is a monadTransaction is a monad
  • 183. STEP 5 (REAL FUN)STEP 5 (REAL FUN) Go monadsGo monadsGo monads Transaction is a monadTransaction is a monadTransaction is a monad
  • 184. Example usingExample usingExample using NeeNeeNee project for aspectsproject for aspectsproject for aspects fun addNewStone(newStone: StoneData) = seq.next().flatMap { addStone(it, newStone) } private fun addStone(stoneId : Long, newStone: StoneData) = Nee.constP(transactional) { jdbcProvider -> val dsl = DSL.using(jdbcProvider.getConnection().getResource()) val insertedRows = dsl.insertInto(Stones.STONES) .values(stoneId, newStone.name, newStone.price) .execute() if (insertedRows == 1) { Option.some(stoneId) } else { Option.none() } }
  • 185. Instead of writing:Instead of writing:Instead of writing: Write this:Write this:Write this: class Hasiok { @Resource val jdbcConnection: Connection @Transactional @Secure @Cacheable @Retryable fun f(p:P) { //code } } class Hasiok { private val f = {jdbcConnection:Connection -> {p: P -> //code } } val enterprisyF = Nee.pure( secure .and(retryable) .and(cacheable) .and(transactional), f) }
  • 188. We need time to adopt to new things /We need time to adopt to new things /We need time to adopt to new things / conceptconceptconcept I understand you still use spring in 2019I understand you still use spring in 2019I understand you still use spring in 2019 Reduce risks / harmReduce risks / harmReduce risks / harm
  • 189. We need time to adopt to new things /We need time to adopt to new things /We need time to adopt to new things / conceptconceptconcept I understand you still use spring in 2019I understand you still use spring in 2019I understand you still use spring in 2019 Reduce risks / harmReduce risks / harmReduce risks / harm
  • 190. Bill G icker image (Bill G icker image (Bill G icker image ( )))https://www. ickr.com/photos/billerr/1814657036https://www. ickr.com/photos/billerr/1814657036https://www. ickr.com/photos/billerr/1814657036
  • 191. Bill G icker image (Bill G icker image (Bill G icker image ( ))) Baby stepsBaby stepsBaby steps https://www. ickr.com/photos/billerr/1814657036https://www. ickr.com/photos/billerr/1814657036https://www. ickr.com/photos/billerr/1814657036
  • 192. Spring 5 -> Spring Web ux is a huge step towards fpSpring 5 -> Spring Web ux is a huge step towards fpSpring 5 -> Spring Web ux is a huge step towards fp
  • 193. Spring 5 -> Spring Web ux is a huge step towards fpSpring 5 -> Spring Web ux is a huge step towards fpSpring 5 -> Spring Web ux is a huge step towards fp I have clean spring web ux based applications without beans !!!I have clean spring web ux based applications without beans !!!I have clean spring web ux based applications without beans !!!
  • 194. Spring 5 -> Spring Web ux is a huge step towards fpSpring 5 -> Spring Web ux is a huge step towards fpSpring 5 -> Spring Web ux is a huge step towards fp I have clean spring web ux based applications without beans !!!I have clean spring web ux based applications without beans !!!I have clean spring web ux based applications without beans !!! Spring is not like a WAR (or Java EE)Spring is not like a WAR (or Java EE)Spring is not like a WAR (or Java EE)
  • 195. Spring 5 -> Spring Web ux is a huge step towards fpSpring 5 -> Spring Web ux is a huge step towards fpSpring 5 -> Spring Web ux is a huge step towards fp I have clean spring web ux based applications without beans !!!I have clean spring web ux based applications without beans !!!I have clean spring web ux based applications without beans !!! Spring is not like a WAR (or Java EE)Spring is not like a WAR (or Java EE)Spring is not like a WAR (or Java EE) It changesIt changesIt changes
  • 196. Spring 5 -> Spring Web ux is a huge step towards fpSpring 5 -> Spring Web ux is a huge step towards fpSpring 5 -> Spring Web ux is a huge step towards fp I have clean spring web ux based applications without beans !!!I have clean spring web ux based applications without beans !!!I have clean spring web ux based applications without beans !!! Spring is not like a WAR (or Java EE)Spring is not like a WAR (or Java EE)Spring is not like a WAR (or Java EE) It changesIt changesIt changes maybe one day spring will not promote beans anymore?maybe one day spring will not promote beans anymore?maybe one day spring will not promote beans anymore?
  • 197. Spring 5 -> Spring Web ux is a huge step towards fpSpring 5 -> Spring Web ux is a huge step towards fpSpring 5 -> Spring Web ux is a huge step towards fp I have clean spring web ux based applications without beans !!!I have clean spring web ux based applications without beans !!!I have clean spring web ux based applications without beans !!! Spring is not like a WAR (or Java EE)Spring is not like a WAR (or Java EE)Spring is not like a WAR (or Java EE) It changesIt changesIt changes maybe one day spring will not promote beans anymore?maybe one day spring will not promote beans anymore?maybe one day spring will not promote beans anymore? They have stopped with XMLs some time agoThey have stopped with XMLs some time agoThey have stopped with XMLs some time ago
  • 199. Thank youThank youThank you @jarek000000@jarek000000@jarek000000 Sources:Sources:Sources: Adam Warski 2017 - The Case against annotations Tomer Gabel - Slaying sacred cows From Spring Boot Apps to Functional Kotlin Nicholas Frankel - plain java Pong server - https://sites.google.com/site/unclebobconsultingllc/blogs-by-robert- martin/dependency-injection-inversion https://www.youtube.com/watch?v=f6a78mCrSeE https://github.com/javaFunAgain/ratpong https://github.com/nee ect/nee