Studying JSR-299, I read section 5.1 of the Weld reference which explains how scopes work in CDI. Apparently, context is a concept closely related to scope. The difference is not clear in my mind and I feel tempted to even use the words interchangeably.
What is the difference between scope and context? What is the relationship between the two concepts?
Each scope has a separate context.
The context is a container for beans which have been defined with the respective scope.
That's why context implementations carry the name of the scope - ApplicationContext, DependentContext, RequestContext, etc.
This is an implementation detail actually - as a user of CDI you should only know about scopes (because you define it for your beans), and the implementation decides where to place those beans and how to manage their lifecycle.
My understanding is that scope refers to where an object may be accessed from, while context enumerates the objects that can be accessed from some particular point in program execution. (That is, we talk about the scope of an object, and the context at some particular point in program execution.)
Mathematically speaking, both describe the can-access relation, but look at it in different directions.
First, we have concepts in our heads like applications, sessions, requests. Let's use the session concept in the following examples.
If we consider that a piece of execution is serving for a particular session, we'll say the session is part of the context of the execution; or, it is the session context of the execution.
A session has some variables, e.g. userName; we'll say the session is the scope of these variables.
Since both are pointing to the same session, it can get confusing. For example,
get the userName from the session context
get the userName from the session scope
both sound fine, because we are talking about an execution on a variable.
The following example is intelligible per the definition of scope
the scope of the injected bean is Session
but we don't have problem understanding what's really going on. If we want to, we can expand it till it's based on basic usages of words; we don't do that because it will be very verbose.
An author faces the difficult task of packing the words succinctly yet expecting readers somehow understand the complex meaning. Texts about context and scope usually appear to be gibberish to those who haven't understood the concepts.
API names are even more difficult to come up with, because codes are not English sentences. Context or Scope are pretty much interchangeable. If there's only one object representing a session, the class probably should be named just Session. If we split the part about variable manipulation, that part can be called SessionScope. However, the meaning of SessionContext is too elusive, the best we can tell, from the name alone, is that it is about something of a session - "context" here is pretty much an expletive.
Related
Is it common practice to communicate via field references. Let's say I have an instance injected all over my program. Since all classes are referencing the same instance I can simply change it's state, instead of informing all dependent classes via method calls? Isn't that a big advantage of dependency injection? Or do I turn a dependency injected variable turn into a global variable?
Variables don't get injected. Values get injected. When you inject a bean into another bean you are injecting that reference. References are values, see
Is Java "pass-by-reference" or "pass-by-value"?.
You can have some spring bean in singleton scope that different parts of the application call, with some method which returns a value. For instance a spring boot application can have a Clock configured that various services or other components have injected into them, where they call the clock to get the current time.
If you do have a bean that contains some mutable value that gets set, be aware its scope will be limited to the application instance. If you have multiple instances of the application deployed. each one will have its own separate bean. Also changes aren't going to be guaranteed to be visible across threads unless you enforce that (with tools like locking, the volatile keyword, atomic variables, etc.).
Fundamentally OO is about message-passing, not about sharing memory. We want to limit global state because it's hard to reason about. Especially when you consider the high-concurrency of a web application and how quickly things can be changing, and how difficult it is to ensure changes are visible, in a lot of cases it's better to find alternatives to global variables.
Assuming that the injected type is configured to use a Singleton, there shouldn't be any behavioral difference between using dependency injection and accessing a Singleton directly.
The advantages to using Dependency Injection generally center around how the code is written, and how it allows you to decouple the consuming classes from the specific requirement for that injected object to actually be a singleton.
For example, if you want to unit-test your consuming class, you probably want complete control over what the class perceives as the current state, and you probably don't want any effects of the code your testing to carry over into other unit tests: you don't want a test to pass when it is run all by itself but fail if it happens to run immediately after some other test.
Using Dependency Injection, your unit tests can encapsulate the entire interaction with the code being tested. The code that instantiates the class has complete control over what gets injected, so it doesn't have to provide a singleton value.
By separating the class that consumes an injected value from any specific knowledge about where that value comes from, or what its life cycle looks like, you're better able to maintain separation of concerns. If a future change requires a value to no longer be a singleton (e.g. maybe it needs to be dependent on the current user), you're in a better position to change how that injected value is provided without having to change code all over your code base.
I am working on a j2ee webapp divided in several modules. I have some metadata such as user name and preferences that I would like to access from everywhere in the app, and maybe also gather data similar to logging information but specific to a request and store it in those metadata so that I could optionally send it back as debug information to the user.
Aside from passing a generic context object throughout every method from the upper presentation classes to the downer daos or using AOP, the only solution that came in mind was using a threadlocal "Context" object very similar to a session BTW, and add a filter for binding it on ongoing request and unbinding it on response.
But such thing feels a little hacky since this breaks several patterns and could possibly make things complicated when it comes to testing and debugging so I wanted to ask if from your experience it is ok to proceed like this?
ThreadLocal is a hack to make up for bad design and/or architecture. It's a terrible practice:
It's a pool of one or more global variables and global variables in any language are bad practice (there's a whole set of problems associated with global variables - search it on the net)
It may lead to memory leaks, in any J2EE container than manages its threads, if you don't handle it well.
What's even worse practice is to use the ThreadLocal in the various layers.
Data communicated from one layer to another should be passed using Transfer Objects (a standard pattern).
It's hard to think of a good justification for using ThreadLocal. Perhaps if you need to communicate some values between 2 layers that have a third/middle layer between them, and you don't have the means to make changes to that middle layer. But if that's the case, I would look for a better middle layer.
In any case, if you store the values in one specific point in the code and retrieve it in another single point, then it may be excusable, otherwise you just never know what side affects any executing method may have on the values in the ThreadLocal.
Personally I prefer passing a context object, as the fact that the same thread is used for processing is an artifact of the implementation, and you shouldn't rely on such artifacts. The moment you want to use other threads, you'll hit a wall.
If those states are encapsulated in a Context object, I think that's clean enough.
When it comes to testing, the best tool is dependency injection. It allows to inject fake dependencies into the object under test.
And all dependency injection frameworks (Spring, CDI, Guice) have the concept of a scope (where request is one of these scopes). Under the hood, beans stored in the request scoped are indeed associated with a ThreadLocal variable, but this is all done by the dependency injection framework.
What I would do is thus to use a DI framework, which would make request-scope objects available anywhere, but without having to look them up, which would break testability. Just inject a request-scoped object where you want to use it, and the DI framework will retrieve it for you.
You must know that a servlet container can / will re-use threads for requests so if you do use ThreadLocals, you'll need to clean up after yourself once the request is finished (perhaps using a filter)
If you are the only developer in the project and you think you gain something: just do it! Because it is your time. But, be prepared to revert the decision and reorganize the code base later, as should be always the case.
Let's say there are ten developers on the project. Everybody might like to have its thread local variable to pass on parameters like currency, locale, roles, maybe it becomes even a HashMap....
I think in the end, not everything which is feasible, should be done. Complexity will strike back on you....
ThreadLocal can lead to memory leak if we do not set null manually once its out of scope.
I am injecting a Stateless session bean in a class that has many static methods.
I would like to access this bean from these Static method. There is no documentation on this one.
So I wondering if its allowed. If yes, any downsides? Recommended / not recommended?
If its allowed? Yes, it can be allowed within container and outside of container.
You can access a EJB from non-EJB. Please check below link.
https://stackoverflow.com/a/9061924/1718893
If the class and EJB are in same project/deployable, then JNDI call should be easy. Few steps mentioned in above link can be skipped.
Recommended in scenario like below -
Depending on scenario, this can be a recommended approach. I came across this situation when I had to implement factory pattern. The EJBs were called only when required and based on conditions. I could have made Factory class itself a EJB. But due to its dependencies on some other decision making components, that was not possible.
Not recommended in scenraio like below -
Depending on how much disciplined development is followed, such approach can be discouraged as well. If all the developers are not much experienced with EJBs, its transaction management and deployment, then down the line, this approach can create dangerous situations.
You can definitely access static method or variables from an instance method or variable... but can not access an instance method or variable from a static method!
These days I used to work with JSF, but there's a "convention" I'm in doubt if I should use. While working with managed beans, people used to name it as XxxxxManagedBean where the prefix can be any name related to your business.
Have you worked like that? Particularly, I don't like that much despite makes search easy. Are you using another convention?
Thanks for answering this simple doubt.
There is no strict convention specified by JSF itself. I've seen the following conventions:
FooBean
FooBacking
FooManager
FooController
FooManagedBean
Or even just Foo which is then placed in a specific package like com.example.controller, com.example.backing or even com.example.view, etc.
I myself tend to use FooManager for application and session scoped beans (e.g. DataManager, UserManager, LocaleManager, etc) and just Foo, or as mandated by my current project, FooBacking (e.g. Login or LoginBacking) for request and view scoped beans, which are each usually tied to a specific <h:form> and/or view.
FooBean is too vague. Really a lot of classes can be marked as javabeans. JSF managed beans, JPA entities, EJBs, data transfer objects, value objects, etc. The Bean naming does not indicate the real responsibility of the class in any way. True, I use often public class Bean or MyBean in my generic code examples in blogs or forum/Q&A answers, but in real world you should avoid that.
FooManagedBean is IMO a poor name, it's not only too long and ugly, but technically, a managed bean is an instance of a backing bean which is managed by some framework (JSF in this case). The class definition itself is really a backing bean, not a managed bean. So a FooBackingBean is technically more correct, but it's still too long and the Bean part is a bit itchy.
Anyway, this is a pretty subjective question which can hardly be answered objectively with The One And Correct answer. It really doesn't matter that much to me or anyone else what you makes of it, as long as you're consistent with it throughout the entire project.
Yes, I searched for questions about backing beans and I found many questions. I read them, and I get some parts of it but I need to ask another question, sorry.
After what I understand backing beans are needed because of JSF MVC pattern. Backing beans are the model. So if you have a page that displays a form, an image and a login box the backing beans will have getter/setter pairs for the data that needs to be exposed or changed in the view. And the backing beans will also have methods related to this such as what happen when you submit the form, login in etc.
So my question is if the statements above is correct, and the number of backing beans you make for the components above is dependent on how much code it is?
Would one backing bean exposing methods and getter/setter pairs for all components on this page be legal and "correct" (meaning that I don't do any wrong) in the same way as making 3 backing beans; one for each component would also be fine.
Does it all boil down to experience to see when you should separate vs. making one backing bean for each page, and also the logical part of it? I heard one guy made a backing bean for each component on the page but it sounds like you end up with a lot of small classes.
I would highly apprciate if somebody could verify and correct me.
It is legal for all components in a view to be bound to one managed bean for properties and actions. IDE tooling may encourage you to do this with a single backing bean.
From a class point of view however this approach lacks granularity and can make the managed beans difficult to test. If a class doesn't have a clearly defined purpose then it can be difficult to assert they are doing that job. See warning sign "Summing up what the class does includes the word “and”". All versions of JSF support dependency injection so it is relatively easy to rely on composition to assemble your managed beans.
This is a somewhat subjective topic and the answer depends on other factors (application scale; view design; page function.)