Skip to content

Commit

Permalink
docs: create CDI lab 2
Browse files Browse the repository at this point in the history
Signed-off-by: Otavio Santana <[email protected]>
  • Loading branch information
otaviojava committed Sep 2, 2023
1 parent ae360e9 commit 457ace8
Showing 1 changed file with 260 additions and 20 deletions.
280 changes: 260 additions & 20 deletions docs/jakarta-ee/cdi-lab-2.md
Original file line number Diff line number Diff line change
@@ -1,36 +1,276 @@
# Jakarta CDI - Lab 2


## 1. The fisrt injection

In this lab, we will explore creating the first injection where Vehicle
interface into a single implementation Car.
## 1. Object lifecycle



In this lab, we will create an object and destroy objects using the Produces and Dispose annotations, respectively.

material-play-box-multiple-outline: Steps

1. Create NumberProducer class that will return a random BigDecimal using the ThreadLocalRandom.
2. In the method that returns this BigDecimal put the jakarta.enterprise.inject.Produces annotation.
3. Create a destroy method with a BigDecimal parameter logging the information.
4. Include the Disposes annotation in the BigDecimal Parameter
5. To test and explore this functionality, create an App3 class and inject the BigDecimal.

```java
import jakarta.enterprise.inject.se.SeContainer;
import jakarta.enterprise.inject.se.SeContainerInitializer;
import java.math.BigDecimal;

public class App3 {

public static void main(String[] args) {

try (SeContainer container = SeContainerInitializer._newInstance_().initialize()) {
BigDecimal value = container.select(BigDecimal.class).get();
}
}
}
```

### :material-check-outline: Solution

??? example "Click to see..."

```java
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.inject.Disposes;
import jakarta.enterprise.inject.Produces;

import java.math.BigDecimal;
import java.util.concurrent.ThreadLocalRandom;

@ApplicationScoped
class NumberProducer {

@Produces
public BigDecimal producer() {
ThreadLocalRandom random = ThreadLocalRandom.current();
double nextDouble = random.nextInt(1, 100);
return new BigDecimal(nextDouble);
}

public void destroy(@Disposes BigDecimal value) {
System.out.println("We don't need this number anymore: " + value);
}
}
```


## 2. Using InjectionPoint



In this lab, we will create an object taking information from who needs this information using the InjectionPoint. Thus, we will create a Logger producer.

material-play-box-multiple-outline: Steps

1. Create a LoggerProducer class
2. Create a method that returns a Logger with `InjectionPoint` as a parameter.
3. Create a Logger with the class name using the `InjectionPoint
.getMember().getDeclaringClass().getName()`.
4. Create a NumberLogger that will inject a `Logger` as a field.
5. To test and explore this functionality, update the `App3` as the show code below:

```java
import jakarta.enterprise.inject.se.SeContainer;
import jakarta.enterprise.inject.se.SeContainerInitializer;

import java.math.BigDecimal;

public class App3 {

public static void main(String[] args) {

try (SeContainer container = SeContainerInitializer.newInstance().initialize()) {
BigDecimal value = container.select(BigDecimal.class).get();
NumberLogger logger = container.select(NumberLogger.class).get();
logger.log(value);
}
}
}
```

### :material-check-outline: Solution

??? example "Click to see..."

```java

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.inject.Produces;
import jakarta.enterprise.inject.spi.InjectionPoint;

import java.util.logging.Logger;

@ApplicationScoped
class LoggerProducer {

private static final Logger LOGGER = Logger.getLogger(LoggerProducer.class.getName());

@Produces
Logger getLog(InjectionPoint ip) {
String declaringClass = ip.getMember().getDeclaringClass().getName();
LOGGER.info("Creating instance log to " + declaringClass);
return Logger.getLogger(declaringClass);
}
}

import jakarta.inject.Inject;

import java.math.BigDecimal;
import java.util.logging.Logger;

public class NumberLogger {

private Logger logger;

NumberLogger() {
}

@Inject
public NumberLogger(Logger logger) {
this.logger = logger;
}

public void log(BigDecimal value) {
this.logger.info("The BigDecimal value is " + value);
}


}
```

## 3. CDI events


In this lab, we will explore more about the CDI events.

material-play-box-multiple-outline: Steps

1. Create a Vehicle interface with the move method without return.
2. Create a Car implementation defined as ApplicationScoped; the move method will log the move into the logs.
1. Create a `News` class to implement `Supplier<String>` returning the News.
2. Create `Magazine`, `NewsPaper`, `SocialMedia` classes implementing `Consumer< News>`.
3. Consume the News, putting the class name and the News using the log. Also, include the `Observers` annotation in the parameter. E.g.:

```java
@Override
public void accept(@Observes News news) {
LOGGER.info("We got the news, we'll publish it on a magazine: " + news.get());
}
```

You can test and explore your solution by creating the App1 class as shown below:
4. Create a Journalist class that will inject the `Event<News>event`.
5. Create a method called `receiveNews` that will receive a `News` instance and then fire the `Event`.
6. For test, create an App4 class with the code below.

```java
public class App1 {
```java

public static void main(String[] args) {
try (SeContainer container = SeContainerInitializer.newInstance().initialize()) {
Vehicle vehicle = container.select(Vehicle.class).get();
vehicle.move();
import expert.os.labs.persistence.nosql.cdi.news.Journalist;
import expert.os.labs.persistence.nosql.cdi.news.News;
import jakarta.enterprise.inject.se.SeContainer;
import jakarta.enterprise.inject.se.SeContainerInitializer;

Car car = container.select(Car.class).get();
car.move();
public class App4 {

System.out.println("Is the same vehicle? " + car.equals(vehicle));
}
}
}
```
public static void main(String[] args) {

try (SeContainer container = SeContainerInitializer.newInstance().initialize()) {
Journalist journalist = container.select(Journalist.class).get();
journalist.receiveNews(News.of("Java 17 has arrived!!"));
}
}
}
```

### :material-check-outline: Solution

??? example "Click to see..."
??? example "Click to see..."

```java

import java.util.Objects;
import java.util.function.Supplier;

public final class News implements Supplier<String> {

private final String name;

private News(String name) {
this.name = name;
}

@Override
public String get() {
return name;
}

public static News of(String news) {
Objects.requireNonNull(news, "news is required");
return new News(news);
}
}

import jakarta.enterprise.event.Observes;

import java.util.function.Consumer;
import java.util.logging.Logger;

public class Magazine implements Consumer<News> {

private static final Logger LOGGER = Logger.getLogger(Magazine.class.getName());

@Override
public void accept(@Observes News news) {
LOGGER.info("We got the news, we'll publish it on a magazine: " + news.get());
}
}

@ApplicationScoped
public class NewsPaper implements Consumer<News> {

private static final Logger LOGGER = Logger.getLogger(NewsPaper.class.getName());

@Override
public void accept(@Observes News news) {
LOGGER.info("We got the news, we'll publish it on a newspaper: " + news.get());
}
}

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.event.Observes;

import java.util.function.Consumer;
import java.util.logging.Logger;

@ApplicationScoped
public class SocialMedia implements Consumer<News> {

private static final Logger LOGGER = Logger.getLogger(SocialMedia.class.getName());

@Override
public void accept(@Observes News news) {
LOGGER.info("We got the news, we'll publish it on Social Media: " + news.get());
}
}

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.event.Event;
import jakarta.inject.Inject;

@ApplicationScoped
public class Journalist {

@Inject
private Event<News> event;

public void receiveNews(News news) {
this.event.fire(news);
}

}

```

0 comments on commit 457ace8

Please sign in to comment.