I'm new to Java and to Spring, and I'm not sure how this example code is working in that "SpringBootRequestHandler" implements the AWS RequestHandler, and also "propagates the request to our function".
The example is found here: https://dzone.com/articles/run-code-with-spring-cloud-function-on-aws-lambda
I've reviewed this code for awhile - and I'm not connecting the dots on how the UppercaseFunction gets invoked via the UppercaseFunctionHandler.
I'll apologize in advance if this isn't the right place to ask this question, but I'm not sure where else I can ask for help!
So UppercaseFunctionHandler extends SpringBootRequestHandler which extends SpringFunctionInitializer which is where the magic happens.
When a request is received, the handler will attempt to initialize the spring context.
During initialization, it will look up the property function.name defined in the application.properties which is the name of function component bean that would of been discovered during component scanning.
So in summary there is a lot of indirection going on here, and it's certainly hard to understand without digging into the framework code and having a bit of knowledge about the way spring works.
Related
So after a lot of searching and banging my head against a brick wall, I figured it was easier to put this question out there to see if anyone can help.
To set the backstory to this question:
I'm currently writing a custom Java framework for a project, which has a small internal DI system that just scans through a class, looks for any fields annotated with #Dependency (provided by the annotations package from my framework) and uses its internal Map to inject instances into those fields.
For reference, this framework is used by client code in the following way:
Client creates a new Singleton instance of the core manager
Client builds classes that extend a Base class and implement whatever logic they desire using the framework
Client registers their class with the manager (essentially: Manager#register(Class<? extends BaseClass)
The manager will then instantiate the client's class and perform its dependency injection as mentioned above
I'm currently working on building Guice support into this framework so that Clients who are using Guice in their code can get their dependencies from Guice if they so desire. I'd ideally like this to work alongside the framework's internal DI, however this is not a hard requirement. To note, the framework itself does not use Guice.
I've currently got two options on my hands from what I can tell:
Option 1: Get the client to pass their Guice injector into my Guice Handler class and let Guice create the classes via injector.getInstance
Option 2: Let the client's Guice injector create my Guice Handler class and have a MembersInjector injected into the handler to then call injectMembers on the class instances where required.
Option 1 from what I can tell is a bad approach, for reasons described here: (https://github.com/google/guice/wiki/InjectingTheInjector)
So I'm currently working towards Option 2. This would require the client code to do something like:
Manager manager = new Manager();
Injector injector = Guice.createInjector(new ClientModule();
manager.enableGuiceSupport(injector.getInstance(GuiceHandler.class) Or:
GuiceHandler guiceHandler = new GuiceHandler();
injector.injectMembers(guiceHandler);
manager.enableGuiceSupport(guiceHandler);
Obviously Guice needs to deal with the GuiceHandler class so that I can get the MembersInjector injected.
Looking at this, whilst a valid solution to the problem, its adding a requirement on the client that feels slightly labored. The aim of the framework is to reduce what the client code needs to do, not add to it.
So my question boils down to this:
Is my approach to Option 2 here a good way to move forward and I just accept that the client needs to "bootstrap" the GuiceHandler?
Or alternatively, is there just a better way to achieve the goal of adding Guice support?
Any thoughts, suggestions and constructive criticism is welcome!
(To everyone who's taken the time to read through all this to see if you can help, have a cookie: 🍪. I really appreciate your time!)
I apologize if some of my terminology is off, I'm still trying to learn:
I'm using the Dropwizard framework and I have a resource class with all my various POST/GET/etc methods. They all work fine when hit from Postman, browsers, etc. If I try something that has no matching path in the resource class I get an exception with HTTP status 405 - method not allowed.
Is there a way to default to some other method where I can display troubleshooting help -- like a list of what the available APIs are or a link to some documentation? Sort of like a try catch type of logic. Not sure what the options are or if there is a best way to do this.
Any help is appreciated. Thanks!
I don't think you might want to do that. REST over HTTP is driven "mostly" by the HTTP method and the end-point the same will act upon it.
In any stack, try to avoid that since you have specific actions for specific resources...anything else should be treated as something the server didn't understand, in the same way the HTTP protocol would behave.
Being said that, just apply a wildcard, usually * to one of the methods as a fallback action. That should work on Jersey and Spring Boot (MVC) as well.
Firstly I tell that I am newbie at spring (on the whole, also AOP). At this moment I have working rest api.
I am trying to use this thread:
Spring Boot - How to log all requests and responses with exceptions in single place?
I am using spring boot and only annotations configuration. I tried to follow this tutorial, however I have simple problems, I ask you for your help ( I tried to read more about AOP, but I would rather implement concrete example and then try to dig deeper ).
1. <aop:aspectj-autoproxy/> Is it possible to express it using only annotations ?
2.
#Retention(RetentionPolicy.RUNTIME)
#Target({ElementType.METHOD,ElementType.TYPE})
public #interface EnableLogging {
ActionType actionType();
}
Where this fragment should resiude ? I tried to conclude and some place, but no effect.
3. What about turning on Aspect ? What does it mean ? For example, what does it mean this line:
#AfterReturning(pointcut = "execution(#co.xyz.aspect.EnableLogging * *(..)) && #annotation(enableLogging) && args(reqArg, reqArg1,..)", returning = "result")
Thanks in advance, answers to this question should help me get better aop.
Haskell, why don't you ask your question in a comment under the answer you are referring to instead of in a new question? Anyway, as for your questions:
Yes, you can replace <aop:aspectj-autoproxy/> by #EnableAspectJAutoProxy, see Spring AOP manual, chapter 11.2.1.
This "fragment" is not a fragment but a full Java annotation declaration. Maybe you want to learn some Java basics before trying complicated stuff like Spring AOP?
Please read the full Spring AOP chapter in order to get a basic understanding of Spring AOP. As for the AspectJ language as such or the meaning of terms such as joinpoint, pointcut, advice, you should read an AspectJ primer. This code snippet expresses the following:
#AfterReturning: The advice method should always run after an intercepted method specified by the following pointcut has returned without an exception.
pointcut: an expression describing where to weave in the subsequent advice code into your original code.
execution(#co.xyz.aspect.EnableLogging * *(..)): whenever a method annotated by #EnableLogging is executed, no matter how many and which types of parameters and not matter which return type it has.
#annotation(enableLogging) binds the method annotation to an advice parameter so you can easily access it from the advice.
args(reqArg, reqArg1,..) binds the first two parameters of the intercepted method to advice parameters so you can easily access those, too.
returning = "result" binds the intercepted method's return value to another advice parameter so you can easily access that one from the advice as well.
I know Spring framework and have worked in it and have used ApplicationContext to instantiate and load beans.
Lets say I write the following piece of code
ApplicationContext context=new ClassPathXmlApplicationContext("appContext.xml");
Now, after the above statement, how do i get to know if the beans, that are defined in appContext.xml, has been instantiated and loaded by Spring?
Note : I want to know it before accessing any bean
Try retrieving one:
MyClass myClass = (MyClass) context.getBean("MyBean");
I agree with Reimeus, and #jbx's comment. If nothing is thrown you should be good to go. If you really want to be sure though, consider using a logger, or even some sort of AOP to trigger an event when a bean is created.
I think I know what you're getting at, and it's something that's hard for us to do as programmers. Dependency injection (What spring does by creating beans in an application context) takes away the step of explicitly creating beans (ie. "Thing something = new Thing()") and that can be frightening, especially in early development when not everything is working, and you're not sure why.
Your objects are instantiated. You've just got to trust that Spring is doing it's thing--it will let you know if it's not :D
(also check out the BeanFactoryPost processor http://javasourcecode.org/html/open-source/spring/spring-3.0.5/org/springframework/beans/factory/config/BeanFactoryPostProcessor.html , it will allow you to see what's there if you really want)
I used a lot annotations in java but I never wrote one. I read though several guides and I am really confused.
They are using annotations like meta information eg names, age etc. That is really confusing because I want to do something different
http://www.developer.com/java/other/article.php/3556176/An-Introduction-to-Java-Annotations.htm
I want to control the function calls.
for example
#Permission(user)
public static void account(){
...
}
So my functions only gets called if the user has the permission, otherwise the user should be redirected to the login page.
I could not find any information, maybe I am using the wrong keyword?
I hope you can clear things up,
Thanks.
You can do that, but with a lot of extra code. Intercepting method calls is part of AOP (aspect oriented programming). You need to make proxies of you target objects, and in the invocation handler parse the annotation.
Luckily, you don't have to do that - since you have a webapp, just use spring/spring-mvc/spring-security. Spring gives you an AOP framework that you can use to define aspects handling your permission logic
Not sure how you can do this by yourself but if you are using Spring they have something that may help
http://static.springsource.org/spring-security/site/docs/3.0.7.RELEASE/reference/el-access.html
I use it my current project and it works well
Something like that should really be done in the function itself (or in some other part of the program). Note that annotations provide data about a program that is not part of the program itself (see this reference).
I think what you are after is an AOP advisor which is run before your method. See here: http://java-questions.com/spring_aop.html
As an alternative to Spring, you could use AspectJ: http://www.andrewewhite.net/wordpress/2010/03/17/aspectj-annotation-tutorial/