I am using slf4j with Spring AOP for logging and Exception purpose.there are some methods in some classes which formed a method chaining. I am able to log at first method's entry and exit point but when this method called another method then AOP is logging only first method's entry and exit point.I want to log every method's entry and and exit point using #Around annotation here is Pseudo code to explain what i want
package com.sample;
public class Test implements T{
#Override
public void show() {
System.out.println("Test.show()");
test();
}
void Test(){
//Want to log entry and exit point of this method whenever this method called by any other method
//The method may belongs to same class or different package's different class
}
spring.xml is something like this
<bean id="exceptionAspect" class="com.sample.ExceptionAspect"/>
<bean id="test" class="com.sample.Test"/>
My Advise class look like
#Aspect
public class LoggingAspect {
#Around(value="execution (* com.sample.*.*(..))||"+
"execution(* some other package.*.*(..))")
public void logAround(ProceedingJoinPoint joinPoint) throws Throwable {
final Logger logger = LoggerFactory.getLogger(joinPoint.getTarget().getClass());
logger.info("Execution of : " + joinPoint.getSignature() + " Started");
joinPoint.proceed();
logger.info("Execution of : " + joinPoint.getSignature() + " completed");
}
}
Client class
package com.test;
public class App {
public static void main(String[] args) throws Exception {
ApplicationContext appContext = new ClassPathXmlApplicationContext(
"classpath:/META-INF/spring.xml");
T test=(T) appContext.getBean("test");
test.show();
}
Any Help is greatly appreciated..
What you are trying to do is not possible with Spring AOP (at least not without some refactoring of the advised methods). The reason for that is that Spring AOP is proxy based, which means for each bean it creates a proxy class and injects it instead of your implementation. A proxy has all the methods of the bean with added aspect functionality. So When you call a method of a bean (actually the proxy of the bean), the aspect code is executed and your method is then called by delegation. So when your method calls other methods the call are performed using the real beans, not the proxies of those - if any are present - hence you don't get the output you are expecting.
You can think of a proxy it looks somehow like that:
class MyBeanProxy implements MyBean {
MyBeanImpl theBean;
public void foo() {
// aspect code
theBean.foo();
}
public void bar() {
// aspect code
theBean.bar();
}
}
Where your bean is something like
interface MyBean {
foo();
bar();
}
#Component("my_bean")
class MyBeanImpl implements MyBean {
public void foo() {
System.out.println("foo");
bar();
}
public void bar() {
System.out.println("bar");
}
}
In the example above, when you call foo() via the proxy then the aspect code is executed, and the delegation to MyBeanImpl#foo() happens, where bar() is being called. Now it becomes obvious that the aspect code for bar() will not be executed.
Now how can you make it work?
1 - Refactor your code in such a way that for methods you want to have the aspect code executed for them the calls happen on the proxy object not on the bean itself. For that you can get the actual proxy and use it to call your methods.
public void foo() {
System.out.println("foo");
MyBean myBeanProxy = (MyBean) AopContext.currentProxy();
myBeanProxy.bar();
}
Note that this method is more of a hack than a clean way to do the job. For example it is obvious that myBeanProxy has no clue of the state of your current object.
2 - Refactor you code in such a way that bar() is in another bean which you can retrieve using your appContext.
3- Use AspectJ: Aspect code is injected into the target classes themselves (The real thing!)
Here is small example using AspectJ
Aspect
package com.aj;
import java.util.Arrays;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
#Aspect
public class MyAspect {
#Around("execution( * com.app.services.*.* (..) )")
public Object callDurationAdvice(ProceedingJoinPoint pjp) throws Throwable {
Signature signature = pjp.getSignature();
Object[] args = pjp.getArgs();
String argList = Arrays.toString(args);
System.out.println(signature.getDeclaringTypeName() +
"." + signature.getName() + "(" + argList + ") started");
long s = System.nanoTime();
Object proceed = pjp.proceed(args);
long e = System.nanoTime();
System.out.println(signature.getDeclaringTypeName() +
"." + signature.getName() + "(" + argList + ") ended after " +
((double)(e-s)/1000000) + " ms");
return proceed;
}
}
One class in some package witch should be target for the aspect
package com.app.services;
public class ServicesVersionInfo {
public static String getVersion() {
return getVersionNumber() + " " + getVersionStage();
}
public static String getVersionNumber() {
return "1.0.0";
}
public static String getVersionStage() {
return "ALPHA";
}
}
The App
package com.app;
import com.app.services.ServicesVersionInfo;
public class App {
public static void main(String[] args) {
System.out.println("App services version: " +
ServicesVersionInfo.getVersion());
}
}
Ran, this should output something lie that
com.app.services.ServicesVersionInfo.getVersion([]) started
com.app.services.ServicesVersionInfo.getVersionNumber([]) started
com.app.services.ServicesVersionInfo.getVersionNumber([]) ended after 0.004862 ms
com.app.services.ServicesVersionInfo.getVersionStage([]) started
com.app.services.ServicesVersionInfo.getVersionStage([]) ended after 0.005673 ms
com.app.services.ServicesVersionInfo.getVersion([]) ended after 0.378877 ms
App services version: 1.0.0 ALPHA
Finally here are some similar questions and further readings:
Spring AOP not working for method call inside another method
Get AOP proxy from the object itself
Spring AOP top problem #1 - aspects are not applied
Related
I am writing a Spring Boot Application. I want to audit methods with my annotation #AuditMetod: For example I have method foo() with the annotation:
#AuditMetod(name = "SomeValue")
foo() {...}
I want to handle and audit such methods like this (the simplest example):
auditMethod(Method method) {
if (method.hasAnnotation(AuditMethod.class)) {
System.out.println (method.getName() + " was called at " + new Date())
}
}
upd
Thanks to #Karthikeyan #Swapnil Khante and #misha2048 I understood, that I need to use AOP. But I have 2 problems:
The only method in Aspect class in not being called and I don't see the inscription "----------ASPECT METHOD IS CALLED-----------" in log
How can I check in aspect method what method it is intercepting. To get an instance of Method class.
Now I have the following code:
Controller:
#PostMapping
#LoggingRest(executor = "USER", method = "CREATE", model = "SUBSCRIPTION")
public ResponseEntity<?> create(#Valid #RequestBody SubscriptionRequestDto dto) {
...
}
Aspect:
`#Aspect
#Slf4j
#Component
public class AuditAspect {
#Pointcut(value = "#annotation(com.aspect.annotations.LoggingRest)")
public void auditMethod(ProceedingJoinPoint proceedingJoinPoint) {
log.info("----------ASPECT METHOD IS CALLED------------");
}`
And annotation:
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.METHOD)
public #interface LoggingRest {
String executor() default "SYSTEM";
String method() default "";
String model() default "";
}
Auditing is a cross-cutting concern and can be handled using AOP.
Another solution would be to use a low-level solution by writing a custom annotation and using a Spring interceptorto write your business logic.
To use the Spring interceptor you will need to implement the HandlerInterceptor interface
Example of the annotation
#Target(ElementType.METHOD)
#Retention(RetentionPolicy.RUNTIME)
public #interface Audit {
boolean active() default true;
}
Interceptor example
#Component
public class AuditInterceptor implements HandlerInterceptor {
#Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
if (handler instanceof HandlerMethod) {
HandlerMethod handlerMethod = (HandlerMethod) handler;
Audit annotation = handlerMethod.getMethodAnnotation(Audit.class);
if (annotation != null && annotation.active()) {
// your business logic
}
}
HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
}
check this interceptor example
I think one of the solutions here, as #Karthikeyan mentioned, is to use Spring AOP.
If you are not aware a brief introduction - spring-aop module implements the aspect oriented programming paradigm. We extract some common functionality, that we generally want to apply to some subset of functions/methods, to an entity called Aspect (see class annotated with #Aspect). This class will contain out cross-cutting functionality - such as auditing, for instance we want to audit the methods execution time, lets say. We just put the code to be executed, the condition, which tell the spring what exact beans methods should be affect by this aspect, see below.
For example, if I can audit the method execution duration with the following very simple example (in my case I said that any public method, returning void inside the Class com.example.stackoverflow.BusinessLogicClass must be inspected by this Aspect):
#SpringBootApplication
#EnableAspectJAutoProxy
public class StackoverflowApplication implements ApplicationRunner {
#Autowired
private BusinessLogicClass businessLogicClass;
public static void main(String[] args) {
SpringApplication.run(StackoverflowApplication.class, args);
}
#Override
public void run(ApplicationArguments args) throws Exception {
businessLogicClass.test();
}
}
#Aspect
#Component
class MyAspectLogicClass {
#Around("execution(public void com.example.stackoverflow.BusinessLogicClass.*(..))")
public Object hangAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
long before = System.currentTimeMillis();
Object returnedValue = proceedingJoinPoint.proceed();
long after = System.currentTimeMillis();
System.out.printf("Retruned in '%s' ms %n", (after - before));
return returnedValue;
}
}
#Component
class BusinessLogicClass {
public void test() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
In my case, I will get the time before method execution, then by the means of
proceedingJoinPoint.proceed() call I delegate the execution to the real method, and then, once I get the response back, I will get the current system time and calculate the execution time, fairly simple.
I hope I have at least directed you somewhere, if you are looking for documentation, this are the resources I suggest you should look for:
https://docs.spring.io/spring-framework/docs/2.5.x/reference/aop.html offical spring doc (stale a bit, but there are some valuable things to learn)
https://docs.spring.io/spring-framework/docs/4.3.15.RELEASE/spring-framework-reference/html/aop.html is more fresh doc
Hope it helped :)
The problem was in right annotation. In Aspect class I tried #Around and everything works as I need.
#Aspect
#Slf4j
#Component
public class AuditAspect {
#Around(value = "#annotation(com.aspect.annotations.LoggingRest)")
public void auditMethod(ProceedingJoinPoint proceedingJoinPoint) {
var method = ((MethodSignature) proceedingJoinPoint.getSignature()).getMethod();
log.info("----------ASPECT METHOD IS CALLED------------");
}
}
For getting a Method instance I use fallowing code
Method method = ((MethodSignature) proceedingJoinPoint.getSignature()).getMethod();
I want to measure execution time of a method which is present in a client library. My application is a spring boot app and I am calling a method present in a class coming from some library. I tried running below code but it does not working. In my case, client class object is not managed by spring container which could be a reason but is there any way to get hold of that method.
#Aspect
#Component
public class LoggingAspect {
public static final Logger logger = LoggerFactory.getLogger(LoggingAspect.class);
#Around("execution(public * Invokers.ApiClient.execute(..))") //okhttp3.Call,
public Object methodTimeLogger(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
MethodSignature methodSignature = (MethodSignature) proceedingJoinPoint.getSignature();
// Get intercepted method details
String className = methodSignature.getDeclaringType().getSimpleName();
String methodName = methodSignature.getName();
// Measure method execution time
StopWatch stopWatch = new StopWatch(className + "->" + methodName);
stopWatch.start(methodName);
Object result = proceedingJoinPoint.proceed();
stopWatch.stop();
System.out.println("----------Start----------");
// Log method execution time
if (logger.isInfoEnabled()) {
logger.info(stopWatch.prettyPrint());
}
System.out.println("----------End----------");
return result;
}
}
I have two methods and one of them with an annotation, let's say:
#ReplacingMethod(bar)
public void foo() { ... }
public void bar { ... }
Is it possible to invoke bar instead of foo whenever foo is called, without jumping into the body of foo? I did some research on this and were not able to set a return value via reflections. Any suggestions?
You can achieve this using Aspect Oriented Programming, e.g. with Spring AOP. I don't think you can change method implementation in pure Java without AOP.
Let me give you an example how to achieve what you asked for with Spring AOP. First, define your annotation:
#Target(ElementType.METHOD)
#Retention(RetentionPolicy.RUNTIME)
public #interface ReplacingMethod {
String value();
}
Then define an aspect that will do the actual replacing of method:
#Aspect // aspect is a module encapsulating your replacing functionality
public class ReplacingAspect {
// pointcut gives an expression selecting the "joint points" to be intercepted
#Pointcut("#annotation(example.annotation.ReplacingMethod)")
public void methodToBeReplaced() { }
// advice defining the code executed at joint points selected by given pointcut;
// in our case #Around is executed instead of the method call selected by pointcut methodToBeReplaced()
#Around("methodToBeReplaced()")
public void replaceMethodCall(ProceedingJoinPoint pjp) throws Throwable {
// get reference to the method to be replaced
MethodSignature signature = (MethodSignature) pjp.getSignature();
Method method = signature.getMethod();
// extract the name of the method to be called from ReplacingMethod annotation
ReplacingMethod replacingMethodAnnotation = method.getAnnotation(ReplacingMethod.class);
String methodToCallName = replacingMethodAnnotation.value();
// use reflection to call the method
Method methodToCall = pjp.getTarget().getClass().getMethod(methodToCallName);
methodToCall.invoke(pjp.getTarget());
}
}
Now, assuming you have class TestClass where you have applied your #ReplacingMethod annotation,
public class TestClass {
#ReplacingMethod("bar")
public void foo() { System.out.println("foo"); }
public void bar() { System.out.println("bar"); }
}
the last missing piece is to get create your instance of TestClass with AOP enabled and your ReplacingAspect applied:
public class Main {
public static void main(String... args) throws Exception {
ApplicationContext context = new AnnotationConfigApplicationContext(TestConfiguration.class); // create Spring context that enables AOP under the hood
TestClass testObject = context.getBean(TestClass.class); // we get reference to TestClass instance from context; calling on a plain new instance wouldn't work
testObject.foo(); // prints "bar" !
}
#EnableAspectJAutoProxy // enables AOP support
#Configuration
public static class TestConfiguration {
#Bean public TestClass testClass() { return new TestClass(); }
#Bean public ReplacingAspect aspect() { return new ReplacingAspect(); } // enables our ReplacingAspect
}
}
You can check out the whole working example at GitHub.
Reflection cannot change the schema of a class and not its behaviour. It can only call (possibly hidden) features.
If you want to replace a method call by another try out a byte code library as asm or javassist. These tools allow you to change class definitions and behaviour (even at runtime with some restrictions).
The approach with AOP is easier, but it is not as flexible and its classpath footprint is larger.
Java Gurus,
I am pretty new for annotations and haven't searched for this a lot, so please bear with me...
I would like to implement a Custom Annotation which will intercept a method call; to start with something very basic it can just print the methods name and parameters so that I could avoid the logger statement.
A sample call like this:
public MyAppObject findMyAppObjectById(Long id) throws MyCustomException {
log.debug("in findMyAppObjectById(" + id + ")");
//....
}
can be converted into:
#LogMethodCall(Logger.DEBUG)
public MyAppObject findMyAppObjectById(Long id) throws MyCustomException {
//....
}
Could I get some hints about this?
Based in your answers of my comments, you will not be able to do this with just annotations. You can, of course, create your annotations and create some reflective code that will detected then and execute some code, but this will not change your code too much, because you will need to call the parser method before you call your methods and I think that will not help you too much, since you will need to call the parser method before each call.
If you need the behavior that you mentioned (automatic call), you will need to combine your annotations with some AOP framework like Spring (plain Java) or AspectJ (AspectJ code). With then, you can set pointcuts and everytime this point is reached, some code may be executed. You can configure then to execute some code before and/or after method execution.
If the first scenario is sufficient, you can do something like:
Logger: enum
public enum Logger {
INFO,
DEBUG;
}
LogMethodCall: annotation
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
#Retention( RetentionPolicy.RUNTIME ) // the annotation will be available during runtime
#Target( ElementType.METHOD ) // this can just used in methods
public #interface LogMethodCall {
Logger logLevel() default Logger.INFO;
}
Person: annotated class
public class Person {
// will use the default log level (INFO)
#LogMethodCall
public void foo( int a ) {
System.out.println( "foo! " + a );
}
#LogMethodCall( logLevel = Logger.DEBUG )
public void bar( int b ) {
System.out.println( "bar! " + b );
}
}
Utils: class with the log static method (this will perform the "parsing")
public class Utils {
public static void log( Object o, String methodName ) {
// gets the object class
Class klass = o.getClass();
// iterate over its methods
for ( Method m : klass.getMethods() ) {
// verify if the method is the wanted one
if ( m.getName().equals( methodName ) ) {
// yes, it is
// so, iterate over its annotations
for ( Annotation a : m.getAnnotations() ) {
// verify if it is a LogMethodCall annotation
if ( a instanceof LogMethodCall ) {
// yes, it is
// so, cast it
LogMethodCall lmc = ( LogMethodCall ) a;
// verify the log level
switch ( lmc.logLevel() ) {
case INFO:
System.out.println( "performing info log for \"" + m.getName() + "\" method" );
break;
case DEBUG:
System.out.println( "performing debug log for \"" + m.getName() + "\" method" );
break;
}
}
}
// method encountered, so the loop can be break
break;
}
}
}
}
AnnotationProcessing: class with code to test the annotation processing
public class AnnotationProcessing {
public static void main(String[] args) {
Person p = new Person();
Utils.log( p, "foo" );
p.foo( 2 );
Utils.log( p, "bar" );
p.bar( 3 );
}
}
Of course, you will need to improve my code to fit your needs. It is just a start point.
More about annotations:
http://docs.oracle.com/javase/1.5.0/docs/guide/language/annotations.html
http://docs.oracle.com/javase/tutorial/java/javaOO/annotations.html
http://tutorials.jenkov.com/java-reflection/annotations.html
More about AOP:
http://en.wikipedia.org/wiki/Aspect-oriented_programming
http://static.springsource.org/spring/docs/3.0.x/reference/aop.html
http://www.eclipse.org/aspectj/
Use Spring AOP along with Java Annotation. Spring AOP negates the requirement for writing a util class for parsing of Java classes using Java Reflection.
Example -
Custom Annotation -
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.METHOD)
public #interface A {
boolean startA() default false;
boolean endA() default false;
}
Aspect-
#Aspect
public class AAspect {
#Pointcut(value = "execution(* *.*(..))")
public void allMethods() {
LOGGER.debug("Inside all methods");
}
#Before("allMethods() && #annotation(A)")
public void startAProcess(JoinPoint pjp, A a) throws Throwable {
if (a.startA()) {
//Do something
}
}
Enable AspectJ -
#Configuration
#EnableAspectJAutoProxy
public class AConfig {
}
Use in code -
#A(startA = true, endA = true)
public void setUp(){
//Do something- logic
}
As already suggested, AOP and annotations is the best option. I would recommend to use a ready-made mechanism from jcabi-aspects (I'm a developer):
#Loggable(Loggable.DEBUG)
public String load(URL url) {
return url.openConnection().getContent();
}
All method calls will be logged to SLF4J.
Is it possible to use CDI to inject parameters into method calls? The expected behaviour would be similar to field injection. The preferred producer is looked up and the product is used.
What I would like to do is this:
public void foo(#Inject Bar bar){
//do stuff
}
or this (with less confusing sytax):
public void foo(){
#Inject
Bar bar;
//do stuff
}
This syntax is illegal in both cases. Is there an alternative? If no - would this be a bad idea for some reason if it were possible?
Thank you
EDIT - I may have made my requirements not clear enough - I would like to be able to call the method directly, leaving the initialization of the bar variable to the container. Jörn Horstmann's and Perception's answer suggest that it is not possible.
Injection points are processed for a bean when it is instantiated by the container, which does limit the number of uses cases for method level injection. The current version of the specification recognizes the following types of method injection:
Initializer method injection
public class MyBean {
private Processor processor;
#Inject
public void setProcessor(final Processor processor) {
this.processor = processor;
}
}
When an instance of MyBean is injected, the processor instance will also be injected, via it's setter method.
Event Observer Methods
public class MyEventHandler {
public void processSomeEvent(#Observes final SomeEvent event) {
}
}
The event instance is injected into the event handling method directly (though, not with the #Inject annotation)
Producer Methods
public class ProcessorFactory {
#Produces public Processor getProcessor(#Inject final Gateway gateway) {
// ...
}
}
Parameters to producer methods automatically get injected.
If what you REALLY want is not something as the parameter of the method (which should be provided by the caller), but a properly initialized instance of a CDI bean each time when the method is called, and fully constructed and injected, then check
javax.inject.Provider<T>
Basically, first inject a provider to the class
#Inject Provider<YourBean> yourBeanProvider;
then, in the method, obtain a new instance
YourBean bean = yourBeanProvider.get();
Hope this helps :)
This question came up when I originally did a search on this topic, and I have since learned that with the release of CDI 1.1 (included in the JavaEE 7 spec), there is now a way to actually do what the OP wanted, partially. You still cannot do
public void foo(#Inject Bar bar){
//do stuff
}
but you can "inject" a local variable, although you do not use #Inject but rather programmatically look up the injected instance like this:
public void foo() {
Instance<Bar> instance = CDI.current().select(Bar.class);
Bar bar = instance.get();
CDI.current().destroy(instance);
// do stuff with bar here
}
Note that the select() method optionally takes any qualifier annotations that you may need to provide. Good luck obtaining instances of java.lang.annotation.Annotation though. It may be easier to iterate through your Instance<Bar> to find the one you want.
I've been told you need to destroy the Instance<Bar> as I have done above, and can verify from experience that the above code works; however, I cannot swear that you need to destroy it.
That feature of CDI is called an "initializer method". The syntax differs from your code in that the whole method is annotated with #Inject, the method parameters can further be annotated by qualifiers to select a specific bean. Section 3.9 of JSR 299 shows the following example, with #Selected being a qualifier that can be omitted if there is only one bean implementation.
#Inject
void setProduct(#Selected Product product) {
this.product = product;
}
Please note that
The application may call initializer methods directly, but then no parameters will be passed to the method by the container.
You can use the BeanManager API in your method to get contextual references, or depending on your ultimate goal you could inject an
Instance<Bar>
outside of the method and use it in the method.
If your goal is to call the method via reflection, it is possible to create an InjectionPoint for each parameter.
Here's an example using CDI-SE:
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.context.Dependent;
import javax.enterprise.context.spi.CreationalContext;
import javax.enterprise.inject.se.SeContainer;
import javax.enterprise.inject.se.SeContainerInitializer;
import javax.enterprise.inject.spi.AnnotatedMethod;
import javax.enterprise.inject.spi.AnnotatedType;
import javax.enterprise.inject.spi.BeanManager;
public class ParameterInjectionExample {
public static class Foo {
// this method will be called by reflection, all parameters will be resolved from the BeanManager
// calling this method will require 2 different Bar instances (which will be destroyed at the end of the invocation)
public void doSomething(Bar bar, Baz baz, Bar bar2) {
System.out.println("got " + bar);
System.out.println("got " + baz);
System.out.println("got " + bar2);
}
}
#Dependent
public static class Bar {
#PostConstruct
public void postConstruct() {
System.out.println("created " + this);
}
#PreDestroy
public void preDestroy() {
System.out.println("destroyed " + this);
}
}
#ApplicationScoped
public static class Baz {
#PostConstruct
public void postConstruct() {
System.out.println("created " + this);
}
#PreDestroy
public void preDestroy() {
System.out.println("destroyed " + this);
}
}
public static Object call(Object target, String methodName, BeanManager beanManager) throws Exception {
AnnotatedType<?> annotatedType = beanManager.createAnnotatedType(target.getClass());
AnnotatedMethod<?> annotatedMethod = annotatedType.getMethods().stream()
.filter(m -> m.getJavaMember().getName().equals(methodName))
.findFirst() // we assume their is only one method with that name (no overloading)
.orElseThrow(NoSuchMethodException::new);
// this creationalContext will be valid for the duration of the method call (to prevent memory leaks for #Dependent beans)
CreationalContext<?> creationalContext = beanManager.createCreationalContext(null);
try {
Object[] args = annotatedMethod.getParameters().stream()
.map(beanManager::createInjectionPoint)
.map(ip -> beanManager.getInjectableReference(ip, creationalContext))
.toArray();
return annotatedMethod.getJavaMember().invoke(target, args);
} finally {
creationalContext.release();
}
}
public static void main(String[] args) throws Exception {
try (SeContainer container = SeContainerInitializer.newInstance().disableDiscovery().addBeanClasses(Bar.class, Baz.class).initialize()) {
System.out.println("beanManager initialized");
call(new Foo(), "doSomething", container.getBeanManager());
System.out.println("closing beanManager");
}
}
}