Skip to content

Commit fa3a748

Browse files
committed
Add event bus and fix slow bean initialization logs
1 parent f2ea401 commit fa3a748

35 files changed

+1340
-196
lines changed

.github/workflows/build.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ jobs:
1414

1515
- name: Skip duplicates and docs
1616
id: skip
17-
uses: fkirc/skip-duplicate-actions@v4
17+
uses: fkirc/skip-duplicate-actions@v5
1818
with:
1919
paths_ignore: '["**/README.md", "LICENSE", ".gitignore", ".editorconfig", ".idea/**"]'
2020

@@ -34,4 +34,4 @@ jobs:
3434
if: steps.skip.outputs.should_skip != 'true'
3535
env:
3636
COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }}
37-
run: ./gradlew build
37+
run: ./gradlew build jacocoTestReport coveralls --scan

README.md

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,14 @@
33
[![Coverage Status](https://coveralls.io/repos/github/coditory/quark-context/badge.svg)](https://coveralls.io/github/coditory/quark-context)
44
[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.coditory.quark/quark-context/badge.svg)](https://mvnrepository.com/artifact/com.coditory.quark/quark-context)
55

6-
> Quark Context is a lightweight and single purpose java library for loading and manipulating configurations
6+
> Lightweight, single purpose, dependency injection java library. Similar to [IoC Container provided by Spring Framework](https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans) but lighter.
77
8-
The idea was to create a small, single-jar library, similar to
9-
the [IoC Container provided by Spring Framework](https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans)
10-
, that is:
11-
12-
- lightweight, no dependencies
13-
- single purpose and is not part of a framework
8+
- lightweight, exactly 3 minimalistic dependencies
9+
- single purpose, not part of a framework
1410
- provides both functional and annotation based API
1511
- has conditional bean registration mechanism
1612
- detects slow bean creation
13+
- provides [event bus](https://github.com/coditory/quark-eventbus) integration
1714

1815
## Installation
1916

build.gradle

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,18 @@ plugins {
44
id 'jacoco'
55
id 'signing'
66
id 'com.github.kt3k.coveralls' version '2.12.0'
7-
id 'com.coditory.build' version '0.1.18'
7+
id 'com.coditory.build' version '0.1.19'
88
id 'io.github.gradle-nexus.publish-plugin' version '1.1.0' apply false
99
}
1010

1111
group = 'com.coditory.quark'
12-
description = 'Coditory Quark Configuration Library'
12+
description = 'Coditory Quark Context Library'
1313

1414
dependencies {
15-
api 'org.slf4j:slf4j-api:2.0.0'
15+
api 'org.slf4j:slf4j-api:2.0.3'
1616
api 'org.jetbrains:annotations:23.0.0'
17-
testImplementation 'com.coditory.quark:quark-config:0.1.5'
18-
testImplementation 'ch.qos.logback:logback-classic:1.4.0'
17+
api 'com.coditory.quark:quark-eventbus:0.0.4'
18+
testImplementation 'ch.qos.logback:logback-classic:1.4.4'
1919
testImplementation 'org.spockframework:spock-core:2.3-groovy-4.0'
2020
testImplementation 'org.skyscreamer:jsonassert:1.5.1'
2121
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package annotated
2+
3+
import ch.qos.logback.classic.Logger
4+
import com.coditory.quark.context.Context
5+
import com.coditory.quark.context.base.CapturingAppender
6+
import org.slf4j.LoggerFactory
7+
import spock.lang.Specification
8+
9+
class SlowBeanCreationSpec extends Specification {
10+
CapturingAppender appender = new CapturingAppender()
11+
12+
void setup() {
13+
Logger rootLogger = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME)
14+
rootLogger.addAppender(appender)
15+
}
16+
17+
void cleanup() {
18+
Logger rootLogger = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME)
19+
rootLogger.detachAppender(appender)
20+
}
21+
22+
def "should log slow bean initialization"() {
23+
given:
24+
Context context = Context.scanPackage(annotated.samples.slow_beans.Bar)
25+
when:
26+
annotated.samples.slow_beans.Baz baz = context.get(annotated.samples.slow_beans.Baz)
27+
28+
then:
29+
List<String> logs = appender.getLogsByMessagePrefix("Slow bean creation")
30+
logs.size() == 1
31+
logs.first().startsWith("[WARN] Slow bean creation. Bean: Bar")
32+
}
33+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package annotated.samples.slow_beans
2+
3+
class Bar {
4+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package annotated.samples.slow_beans
2+
3+
class Baz {
4+
final Bar bar
5+
6+
Baz(Bar bar) {
7+
this.bar = bar
8+
}
9+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package annotated.samples.slow_beans
2+
3+
import com.coditory.quark.context.annotations.Bean
4+
import com.coditory.quark.context.annotations.Configuration
5+
6+
@Configuration
7+
class ConfigInit {
8+
@Bean
9+
annotated.samples.slow_beans.Bar bar() {
10+
Thread.sleep(1_000)
11+
return new annotated.samples.slow_beans.Bar()
12+
}
13+
14+
@Bean
15+
annotated.samples.slow_beans.Baz baz(annotated.samples.slow_beans.Bar bar) {
16+
return new annotated.samples.slow_beans.Baz(bar)
17+
}
18+
19+
@Bean
20+
annotated.samples.slow_beans.Foo foo(annotated.samples.slow_beans.Baz baz) {
21+
Thread.sleep(1_000)
22+
return new annotated.samples.slow_beans.Foo(baz)
23+
}
24+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package annotated.samples.slow_beans
2+
3+
import static java.util.Objects.requireNonNull
4+
5+
class Foo {
6+
final Baz baz
7+
8+
Foo(Baz baz) {
9+
this.baz = requireNonNull(baz)
10+
}
11+
12+
Foo(Bar bar) {
13+
throw new IllegalStateException("This constructor should not be used")
14+
}
15+
}
Lines changed: 9 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
package com.coditory.quark.context;
22

3-
import java.util.Objects;
4-
53
import static java.util.Objects.requireNonNull;
64

7-
final class BeanDescriptor<T> {
5+
public record BeanDescriptor<T>(Class<T> type, String name) {
86
public static <T> BeanDescriptor<T> descriptor(Class<T> type) {
97
return new BeanDescriptor<>(type, null);
108
}
@@ -13,51 +11,29 @@ public static <T> BeanDescriptor<T> descriptor(Class<T> type, String name) {
1311
return new BeanDescriptor<>(type, name);
1412
}
1513

16-
private final String name;
17-
private final Class<T> type;
18-
19-
private BeanDescriptor(Class<T> type, String name) {
14+
public BeanDescriptor(Class<T> type, String name) {
2015
this.type = requireNonNull(type);
2116
this.name = name == null || name.isBlank() ? null : name;
2217
}
2318

24-
<R> BeanDescriptor<R> withType(Class<R> type) {
19+
public <R> BeanDescriptor<R> withType(Class<R> type) {
2520
return new BeanDescriptor<>(type, name);
2621
}
2722

28-
String getName() {
29-
return name;
23+
public boolean hasName() {
24+
return name != null;
3025
}
3126

32-
Class<T> getType() {
33-
return type;
27+
public String toShortString() {
28+
return name != null
29+
? type.getSimpleName() + ":" + name
30+
: type.getSimpleName();
3431
}
3532

3633
@Override
3734
public String toString() {
38-
return "BeanDescriptor{" +
39-
"name='" + name + '\'' +
40-
", type=" + type +
41-
'}';
42-
}
43-
44-
String toShortString() {
4535
return name != null
4636
? type.getSimpleName() + ":" + name
4737
: type.getSimpleName();
4838
}
49-
50-
@Override
51-
public boolean equals(Object o) {
52-
if (this == o) return true;
53-
if (o == null || getClass() != o.getClass()) return false;
54-
BeanDescriptor<?> that = (BeanDescriptor<?>) o;
55-
return Objects.equals(name, that.name)
56-
&& Objects.equals(type, that.type);
57-
}
58-
59-
@Override
60-
public int hashCode() {
61-
return Objects.hash(name, type);
62-
}
6339
}

src/main/java/com/coditory/quark/context/BeanFinalizer.java

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,6 @@ private static void closeBean(Object bean, BeanDescriptor<?> descriptor, Method
3838
throw new BeanFinalizationException("Could not close bean: " + descriptor.toShortString() + " using method: " + simplifyMethodName(method), e);
3939
}
4040
log.debug("Closed bean {} using method {} in {}", descriptor.toShortString(), simplifyMethodName(method), timer.measureAndFormat());
41-
if (timer.isOverThreshold()) {
42-
log.warn("Detected long bean close operation. Bean: {}, Method: {}, Time: {}", descriptor.toShortString(), simplifyMethodName(method), timer.measureAndFormat());
43-
}
4441
}
4542

4643
private static void closeBean(Closeable bean, BeanDescriptor<?> descriptor) {
@@ -51,8 +48,5 @@ private static void closeBean(Closeable bean, BeanDescriptor<?> descriptor) {
5148
throw new BeanFinalizationException("Could not close bean: " + descriptor.toShortString(), e);
5249
}
5350
log.debug("Closed bean {} in {}", descriptor.toShortString(), timer.measureAndFormat());
54-
if (timer.isOverThreshold()) {
55-
log.warn("Detected long bean close operation. Bean: {}, Time: {}", descriptor.toShortString(), timer.measureAndFormat());
56-
}
5751
}
5852
}

0 commit comments

Comments
 (0)