🏰 EJB Services: Your Bean’s Superpowers!
Imagine your Enterprise Java Bean is like a superhero. On its own, it can do basic things. But with EJB Services, your superhero gets amazing superpowers!
🎯 The Big Picture
Think of EJB Services like special tools in a toolbox:
| Tool | What It Does |
|---|---|
| ⏰ Timer Service | Wakes up your bean at specific times |
| 🚀 Async Methods | Does work in the background |
| 🛡️ Interceptors | Guards that check things before/after |
| 🔐 Security | Decides who can do what |
⏰ EJB Timer Service
The Story
Imagine you have a pet robot. You want it to:
- Feed your fish every morning at 8 AM
- Send you a reminder every Friday
- Check the mailbox every hour
The Timer Service is like setting alarms for your bean!
How It Works
@Stateless
public class FishFeeder {
@Schedule(hour = "8",
minute = "0")
public void feedFish() {
System.out.println("Feeding fish!");
}
}
What just happened?
@Schedule= “Wake me up at this time”hour = "8"= 8 o’clockminute = "0"= exactly on the hour
Two Types of Timers
graph TD A["Timer Types"] --> B["📅 Automatic"] A --> C["🔧 Programmatic"] B --> D["Uses @Schedule<br>Set once, runs forever"] C --> E["Create timers in code<br>More flexible"]
Programmatic Timer Example
@Stateless
public class ReminderService {
@Resource
TimerService timerService;
public void setReminder(
String message,
long delayMs
) {
timerService
.createTimer(delayMs, message);
}
@Timeout
public void remind(Timer timer) {
String msg = (String) timer.getInfo();
System.out.println("Reminder: " + msg);
}
}
Key Parts:
@Resource TimerService= “Give me the timer tool”createTimer(delay, info)= “Ring after X milliseconds”@Timeout= “This method runs when timer rings”
Real-Life Uses
| Use Case | Schedule Example |
|---|---|
| Daily backup | @Schedule(hour="2") |
| Every Monday | @Schedule(dayOfWeek="Mon") |
| Every 5 min | @Schedule(minute="*/5") |
🚀 Asynchronous Methods
The Story
Imagine you’re at a pizza restaurant:
- Synchronous: You order, stand at counter, wait 20 minutes, get pizza
- Asynchronous: You order, get a ticket, sit down, they call you when ready!
Async methods let your code do other things while waiting!
Simple Example
@Stateless
public class EmailService {
@Asynchronous
public void sendEmail(String to,
String msg) {
// Takes 5 seconds...
// But caller doesn't wait!
sendToServer(to, msg);
}
}
The Magic:
- Add
@Asynchronousannotation - Caller immediately continues
- Method runs in background
Getting Results Back
What if you need the result later?
@Stateless
public class ReportService {
@Asynchronous
public Future<Report> generate() {
Report r = buildBigReport();
return new AsyncResult<>(r);
}
}
Using it:
// Start the work
Future<Report> future =
reportService.generate();
// Do other stuff...
doOtherWork();
// Now get the result
Report report = future.get();
Why Use Async?
graph TD A["User clicks button"] --> B["Start async task"] B --> C["Show &#39;Processing...&#39;"] B --> D["Task runs in background"] D --> E["Task completes"] E --> F["Notify user"]
Benefits:
- App stays responsive
- Can do multiple things at once
- User doesn’t freeze and wait
🛡️ EJB Interceptors
The Story
Think of a bouncer at a club:
- Checks your ID before you enter
- Stamps your hand after you leave
Interceptors are code bouncers! They run before and after your methods.
Simple Interceptor
public class LoggingInterceptor {
@AroundInvoke
public Object log(
InvocationContext ctx
) throws Exception {
String method =
ctx.getMethod().getName();
System.out.println(
"BEFORE: " + method);
Object result = ctx.proceed();
System.out.println(
"AFTER: " + method);
return result;
}
}
What’s happening:
@AroundInvoke= “Wrap around method calls”- Code before
proceed()runs BEFORE ctx.proceed()= Run the actual method- Code after
proceed()runs AFTER
Using Your Interceptor
@Stateless
@Interceptors(LoggingInterceptor.class)
public class OrderService {
public void placeOrder(Order o) {
// This gets logged!
saveOrder(o);
}
}
Common Interceptor Uses
graph TD A["Interceptor Uses"] --> B["📝 Logging"] A --> C["⏱️ Performance"] A --> D["✅ Validation"] A --> E["🔐 Security"] B --> F["Log method calls"] C --> G["Measure time taken"] D --> H["Check input data"] E --> I["Verify permissions"]
Performance Interceptor Example
public class TimingInterceptor {
@AroundInvoke
public Object time(
InvocationContext ctx
) throws Exception {
long start =
System.currentTimeMillis();
Object result = ctx.proceed();
long time =
System.currentTimeMillis() - start;
System.out.println(
"Took " + time + "ms");
return result;
}
}
🔐 EJB Security
The Story
Think of a castle:
- Some rooms are for everyone (lobby)
- Some rooms need a key (private quarters)
- Some rooms are only for the king (throne room)
EJB Security controls who can access what!
Two Main Approaches
| Approach | Description |
|---|---|
| Declarative | Use annotations (easier) |
| Programmatic | Check in code (flexible) |
Declarative Security (Annotations)
@Stateless
public class BankService {
@PermitAll
public double getBalance(
String account
) {
return findBalance(account);
}
@RolesAllowed("MANAGER")
public void approveLoan(
Loan loan
) {
approve(loan);
}
@DenyAll
public void dangerousMethod() {
// No one can call this!
}
}
The Annotations:
@PermitAll= Anyone can call this@RolesAllowed("ROLE")= Only this role@DenyAll= Nobody can call this
Programmatic Security
@Stateless
public class SecureService {
@Resource
SessionContext ctx;
public void doSomething() {
// Check who's calling
String user =
ctx.getCallerPrincipal()
.getName();
// Check their role
if (ctx.isCallerInRole("ADMIN")) {
doAdminStuff();
} else {
doRegularStuff();
}
}
}
Security Flow
graph TD A["User calls method"] --> B{Has required role?} B -->|Yes| C["Method executes"] B -->|No| D["AccessException thrown"] C --> E["Return result"] D --> F["User sees error"]
Role Mapping
@Stateless
@DeclareRoles({"ADMIN", "USER", "GUEST"})
public class MyService {
@RolesAllowed("ADMIN")
public void adminOnly() { }
@RolesAllowed({"ADMIN", "USER"})
public void membersOnly() { }
@PermitAll
public void everyoneWelcome() { }
}
🎮 How They Work Together
Imagine an online store:
graph TD A["Customer places order"] --> B["Security checks role"] B --> C["Interceptor logs start"] C --> D["processOrder method runs"] D --> E["Async: Send confirmation email"] D --> F["Timer: Schedule delivery check"] E --> G["Email sent in background"] F --> H["Check status every hour"] D --> I["Interceptor logs end"]
Real Example
@Stateless
@Interceptors(LoggingInterceptor.class)
public class OrderService {
@Resource
TimerService timer;
@EJB
EmailService email;
@RolesAllowed("CUSTOMER")
public void placeOrder(Order order) {
// Security: Only customers
// Interceptor: Logs this call
saveOrder(order);
// Async: Email in background
email.sendConfirmation(order);
// Timer: Check in 24 hours
timer.createTimer(
86400000,
order.getId()
);
}
@Timeout
public void checkDelivery(Timer t) {
Long orderId = (Long) t.getInfo();
verifyDelivered(orderId);
}
}
🧠 Quick Summary
| Service | One-Line Description |
|---|---|
| ⏰ Timer | Schedule methods to run later |
| 🚀 Async | Run methods without waiting |
| 🛡️ Interceptors | Add behavior before/after methods |
| 🔐 Security | Control who can call what |
💡 Remember This!
Timer = Alarm clock for beans Async = Pizza ticket system (order and wait) Interceptors = Bouncers at the club Security = Castle doors with locks
Your EJB beans now have superpowers! Use them wisely. 🦸♂️
