theme: OCI White slidenumbers: false [.hide-footer]
Building a Framework for the Future
- Graeme Rocher
- Creator of Grails and Micronaut
- Principal Engineer at Object Computing
- Oracle Groundbreaker Award Winner
- Introduction to Micronaut
- Challenges Facing Java
- Micronaut's Approach to Solving The Problems
- Demos!
- A Microservices and Serverless Focused framework (hence the branding)
- Also a Complete Application Framework for any type of Application
- Dependency Injection, Aspect Oriented Programming (AOP), Configuration Management, Bean Introspection and more..
- Microservices
- Serverless Applications
- Message-Driven Applications with Kafka/Rabbit
- CLI Applications
- Even Android Applications
- Anything with
static void main(String..args)
- An Application Framework for the Future
- Reflection Free, Runtime Proxy Free, No Dynamic Classloading (in 1.1)
- Ahead of Time (AOT) Compilation AOT APIs
- ... oh and let's you build Microservices
- Challenges to using Java in Serverless / Microservices scenarios
- Existing Tools and Frameworks Not Optimized for Cold Starts / Low Memory
- Go, Node etc. better in this regards
- Tim Bray (Amazon/AWS) and others not recommending Java
- Greatly Exaggerated (Java has been dead forever)
- Java can be Fast! (see Android and Micronaut)
- However Most Existing Tools are based around
- Reflection
- Runtime Proxies
- Runtime Byte Code Generation (bytebuddy/cglib)
- A New Universal Virtual Machine from Oracle
- Features a
native-image
Tool- Converts Java -> native machine code using AOT
- Works well with Micronaut
- Startup time 20ms and Memory Consumption 18MB!
- GraalVM is cool and a project to keep an eye on
- Still in beta and experimental
- Micronaut optimizes for GraalVM, but also optimizes for regular Java (what most people use today)
- Limited Annotation API
- Type Erasure
- Slow Reflection
- Reflective Data Caches
- Classpath Scanning
- Slow Dynamic Class Loading
@Introspected
class MyBean {
private List<String> names; //getter/setter omitted
}
- AOT Reflection-free replacement for
java.beans.Introspector
- Set/get bean properties, create instances
- Includes
AnnotationMetadata
AnnotationMetadata metadata = BeanIntrospection.getIntrospection(MyBean.class)
.getAnnotationMetadata();
if (metadata.hasStereotype(SomeAnnotation.class)) {
// do stuff
}
- AOT Computed / Merged Annotation data from class/interface hierarchy
- Includes knowledge of meta-annotations
BeanProperty<MyBean, List> property =
introspection.getRequireProperty("names", List.class);
// returns an Argument with an underlying type of String
Optional<Argument> typeVariable = property.asArgument()
.getFirstTypeVariable()
- AOT Computed Generic Type information
- No type erasure / crazly reflection logic to get the type argument
- Precomputes Everything
- Annotation Metadata (see
AnnotationMetadata
interface) - Generic Types (No Type Erasure!)
- Class Loading Requirements (No Dynamic Class Loading!)
ApplicationContext ctx = ApplicationContext.run();
BeanDefinition<MyBean> definition
= ctx.getBeanDefinition(MyBean.class);
- Contains precompuated
AnnotationMetadata
and generic type info - Used by
ApplicationContext
to instantiate beans
- Bean definitions produced for any
@Singleton
- Constructor injection used by default
- Use
@Factory
for beans you cannot annotate - Compliant with
javax.inject
spec and TCK
@ConfigurationProperties("example")
class ExampleConfiguration {
// getters/setters omitted
private String name;
}
ApplicationContext context = ApplicationContext.run("example.name":"Demo");
FooConfiguration config = context.getBean(FooConfiguration);
assert config.name == 'Demo'
@Requires(property="example.enabled")
@Requires(beans=DataSource.class)
@Requires(missingBeans=Example.class)
@Singleton
class DefaultExampleBean implements Example {
...
}
ApplicationContext context = ApplicationContext.run("example.enabled":"true")
Example example = context.getBean(Example)
@Scheduled(fixedRate = "5m") // @Scheduled annotated with @Executable
void everyFiveMinutes() {
messageService.sendMessage("Hello World");
}
- Common Stereotype annotation
- Identifies where framework invokes your code
- Produces reflection-free
ExectubleMethod
instance
public class ScheduledMethodProcessor
implements ExecutableMethodProcessor<Scheduled> {
public void process(BeanDefinition<?> beanDefinition,
ExecutableMethod<?, ?> method) {
// do stuff with the bean
}
}
- Processes only methods annotated by type argument
- In the above case setting up a scheduled job
@Retryable // @Retryable is annotated with @Around
void invokeMe() {
// do stuff
}
- Intercepts a method with a
MethodInterceptor
- No runtime proxies (compile time proxies) or reflection needed
@Around
@Type(DefaultRetryInterceptor.class)
public @interface Retryable {
// annotation attributes
}
- Use
@Type
to specify the implementation - At compilation Micronaut applies the AOP advise
@Client("/hello") // @Client is annotated with @Introduction
public interface HelloClient {
@Get("/")
Single hello();
}
- Introduction AOP advise implements abstract behaviour
- Interfaces or abstract classes
@Introduction
@Type(HttpClientIntroductionAdvice.class)
@Recoverable
@Singleton
public @interface Client {
}
@Type
used again to specify implementation- Can apply other annotations as meta annotations
- Micronaut Provides an Awesome Foundation
- Sacrifices Compilation Speed to Gain so Much More
- Solves Problems with Spring, Jakarta EE and Java in General
- Opens the Door to GraalVM Native