i am very new to this ejb stuff. is there any possibility that in a single file i can have multiple injections based on some criteria.
for eg
public interface common(){
public void sayhello();
}
beanA
implements common()
beanB
implements common()
both are stateless beans
now i have a client which needs to trigger hello method based on some criteria. for eg. say based on console input if string contains A then beanA should be injected otherwise beanB.
Is there any possibility? and again my next question is , can i say this dynamic injection is not managed by container? if so how can i let container take the control? i need a sample code or atleast any tutorial ref.
thanks in advance!!
No, this is not really possible. You might be able to get close with a custom CDI scope that uses a thread local or session attribute, but I wouldn't recommend it. Instead, just inject a reference to both EJBs, and select the one to use as needed:
#EJB(beanName="BeanA")
Common beanA;
#EJB(beanName="BeanB")
Common beanB;
private Common getCommon(String input) {
return isBeanAInput(input) ? beanA : beanB;
}
you could do something like this:
public interfaces ICommon {
public void sayhello();
}
#Stateless
#LocalHome
public class BeanA implements ICommon {
public void sayhello() {
// say hallo
}
}
#Stateless
#LocalHome
public class BeanB implements ICommon {
public void sayhello() {
// say hallo
}
}
and here the CDI "client" which uses the EJB services
#Model
public void MyJSFControllerBean {
#Inject
private BeanA beanA;
#Inject
private BeanB beanB;
public String sayhello(final String input) {
if("a".equals(input)) {
beanA.sayhello();
} else {
beanB.sayhello();
}
return "success";
}
}
Or the other solution would be that you create a CDI producer to create this. but then you are mixing two different concepts. but i think it depends ou your concrete usecase.
dynamic injection does not exist! with #Produce and #Qualifier you can control the creation of the required CDI beans to inject. but this is only for CDI not for EJB.
here the CDI producer example:
public void ICommonProducer {
#EJB
private BeanA beanA;
#EJB
private BeanB beanB;
#Produces
public ICommon produce() {
final String input = "?????";
// but here you have the problem that must get the input from elsewhere....
if("a".equals(input)) {
beanA.sayhello();
} else {
beanB.sayhello();
}
}
}
#Model
public void MyJSFControllerBean {
#Inject
private ICommon common;
public String sayhello(final String input) {
common.sayhello();
return "success";
}
}
i have not teseted this code...
Related
I am learning Java, but found the following piece of code. I am confused. What is bind(X.class).to(X.class); for?
import org.glassfish.hk2.utilities.binding.AbstractBinder;
public class ApplicationBinder extends AbstractBinder {
#Override
protected void configure() {
bind(X.class).to(X.class);
}
}
Thanks
You're configuring how you want your services to be discovered in the DI (dependency injection) system. bind(Service).to(Contract) is basically saying that you want to provide the Service as an injectable service, and want to "advertise" it as Contract. By "advertise", I mean what you want to be able to inject it as. For instance Service can be UserRepositoryImpl, while Contract can be UserRepository (interface). With this you would only be able #Inject UserRepository as that's what you advertise. The benefit of this is all the benefits that come with programming to an interface.
Example
interface UserRepository {
List<User> findAll();
}
class UserRepositoryImpl implements UserRepository {
#Override
public List<User> findAll() {
return Arrays.asList(new User("username"));
}
}
#Path("users")
class UserResource {
#Inject
private UserRepository repository;
#GET
public List<User> getUsers() {
return repository.findAll();
}
}
class JerseyApp extends ResourceConfig {
public JerseyApp() {
register(UserResource.class);
register(new AbstractBinder() {
#Override
public void configure() {
bind(UserRepositoryImpl.class)
.to(UserRepository.class);
}
});
}
}
Here the UserRepository is injected into the UserResource. When the DI system injects it, it will actually be the UserRepositoryImpl instance.
By doing that you are actually binding a new contract to a service.
bind(Service.class).to(Contract.class);
OR (binding a new contract to a service in Singleton)
bind(Service.class).to(Contract.class)..in(Singleton.class);
When there are multiple named implementations for a given interface, how does the container (I am using Unity in a Prism application) know which one to inject unless I call the container.Resolve with the registered name? Here is a simple example:
public interface IDependencyClass
{
void DoSomething();
}
public class DependencyClassA : IDependencyClass
{
void DoSomething() { }
}
public class DependencyClassB : IDependencyClass
{
void DoSomething() { }
}
public interface IConsumer
{
void TakeUserSpecificAction();
}
public class Consumer : IConsumer
{
IDependencyClass dependencyInstance;
public Consumer(IDependencyClass _dependencyInstance)
{
dependencyInstance = _dependencyInstance;
}
public void TakeUserSpecificAction()
{
dependencyInstance.DoSomething();
}
}
public class MyBootStrapper : UnityBootstrapper
{
protected override void ConfigureContainer()
{
base.ConfigureContainer();
Container.RegisterType<IDependencyClass, DependencyClassA>( "InstanceA" );
Container.RegisterType<IDependencyClass, DependencyClassB>( "InstanceB" );
Container.RegisterType<IConsumer, Consumer>();
}
}
and here is my MainViewModel from my application. The "RaiseSomeCommand" command is not enabled until the user has logged in. When it is enabled, it can execute the ReaiseConsumerCommandRequest, which in turn calls the consumer. Here is my ViewModel.
public class MainWindowViewModel
{
private readonly IRegionManager regionManager;
private readonly ILoginService loginService;
private readonly IConsumer consumer;
public ICommand RaiseSomeCommand { get; set; }
public MainWindowViewModel( IRegionManager regMgr, ILoginService _loginService, IConsumer _consumer )
{
regionManager = regMgr;
loginService = _loginService;
consumer = _consumer;
NavigateCommand = new DelegateCommand<string>( Navigate );
LoginViewRequest = new InteractionRequest<INotification>();
RaiseSomeCommand = new DelegateCommand( RaiseConsumerCommandRequest );
}
private void RaiseConsumerCommandRequest()
{
consumer.TakeUserSpecificAction();
}
}
So, when I execute
consumer.TakeUserSpecificAction();
which DependencyClass instance am I using? DependencyClassA or DependencyClassB. Also, If I want to use specifically say DependencyClassB, What do I need to do to make it happen. I don't want to call
container.Reslove<IDependencyClass>("InstanceB")
in my ViewModel because I am then using the container as a service locator. I am also passing the container reference around.
I have seen in some code examples that the constructor parameter for the consumer class is decorated with a Dependency attribute like below.
public class Consumer
{
IDependencyClass dependencyInstance;
public Consumer([Dependency("InstanceB")]IDependencyClass _dependencyInstance)
{
dependencyInstance = _dependencyInstance;
}
}
But then, I am putting a hard constraint on the Consumer to use only the "InstanceB" implementation. Secondly, I am creating a dependency to Unity. Thirdly, now I have to clone the Consumer class to use "InstanceA" Implementation. That goes against the DRY principle.
I have heard that these conditions are application decisions and not an IoC related logic. I can agree with that argument. But then, where and how in the application would I resolve the right implementation without violating one rule or another?
I can't see how I can inject the right concrete instance unless I choose to use one of the above two options. Container.Resolve or Dependency attribute. Can anybody help please?
I'm trying to implement dependency injection but i know how to implement the interface and repository of classes then i don't know what shall i do.
This my sample:
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public string LastName { get; set; }
}
This is my interface:
public interface IUser
{
IEnumerable<User> GetUsers();
void AddUser(User user);
void EditUser(User user);
void DeleteUser(int id);
User UserGetById(int id);
void Save();
}
This is my repository:
public class UserRepsitory:IUser
{
private _Context _context;
public UserRepsitory(_Context _context)
{
this._context = _context;
}
public IEnumerable<User> GetUsers()
{
return _context.User.ToList();
}
public void AddUser(User user)
{
_context.User.Add(user);
}
public void EditUser(User user)
{
_context.Entry(user).State = System.Data.Entity.EntityState.Modified;
}
public User UserGetById(int id)
{
return _context.User.Find(id);
}
public void Save()
{
_context.SaveChanges();
}
public void DeleteUser(int id)
{
var Search = _context.User.Find(id);
_context.User.Remove(Search);
}
}
And one of method in controller:
private IUser userRepsitory;
public UsersController()
{
this.userRepsitory = new UserRepsitory(new _Context());
}
public UsersController(IUser UserRepository)
{
this.userRepsitory = UserRepository;
}
public ActionResult Index()
{
return View(userRepsitory.GetUsers());
}
What is the next step?
The first thing is, get rid of the default constructor where we are hard coding the initialization of UserRepository ! We will do that in the dependency injection way.
public UsersController : Controller
{
private readonly IUser userRepsitory;
public UsersController(IUser UserRepository)
{
this.userRepsitory = UserRepository;
}
public ActionResult Index()
{
return View(userRepsitory.GetUsers());
}
}
Now we need something to tell the MVC framework which version/implementation of IUser should be used when the code runs. you can use any dependency injection frameworks to do that. For example, If you are in MVC 6, you can use the inbuilt dependency injection framework to do that. So go to your Startup class and in your ConfigureServices method, you can map an interface to a concrete implementation.
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<IUser, UserRepository>();
}
}
If you are in a previous version of MVC, you may consider using any of the dependency injection frameworks available like Unity, Ninject etc.
It is pretty much same, you map an interface to a concrete implementation
Ninject
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IUser>().To<UserRepository>();
}
You do not need to put the mapping in a cs file. You can define that in a config file. For example, when you use Unity you can do something like this in your config file (web config or an external config file for unity configuration)
Unity
<alias alias="IUser" type="YourNamespace.IUser, YourAssemblyName" />
<register type="IUser" mapTo="YourNamespace.UseRepository, YourAssemblyName">
In order to create and configure your project with Spring DI(Dependency Feature) you must configure beans.
Create an xml file (if its not there) and add references to bean
In this xml file, provide references to the classes you want to inject. Example:
<bean id="Name of the JAVA Class" class="the Full path of the JAVA class"/>
And in your class where you are supposed to call the referencing class(above), calling procedure would be like :
#Controller
public class MyController {
private full.path.of.my.class.named.MyJavaClass _class;
#Autowired
private MyController (full.path.of.my.class.MyJavaClass class)
{
this._class= class;
}
}
Now say if you a function in MyJavaClass
public int sum(int x, int y){
return x+y;
}
Then without creating object of MyJavaClass you can inject like the following in your controller:
_class.Sum(10,15);
YOU DO NOT CREATE AN INSTANCE OF THIS CLASS.
I have a Java EE 6 web application and use the WebSocket protocol to communicate with browsers. The browser can send various types of messages and in the servers onMessage method I would like to route (or dispatch) the message to a specific message handler class depending on the message type. I would like to configure or register these message handlers via annotations, similar to the mechanism of servlets (#WebServlet("/there")). And like in servlets, I would like to be able to use CDI injection in the message handlers.
For now I have a MessageType annotation, a MessageHandler interface and 3 implementations.
#Documented
#Target(ElementType.TYPE)
#Retention(RetentionPolicy.RUNTIME)
public #interface MessageType
{
String value();
}
public interface MessageHandler
{
public void processMessage(String inputMesssage);
}
#MessageType("first")
public class FirstMessageHandler implements MessageHandler
{
#Inject
ResourceBundleProvider resourceBundleProvider;
#Override
public void processMessage(String inputMesssage)
{
System.out.println("FirstMessageHandler#processMessage: " + inputMesssage);
System.out.println("InjectionTest: " + resourceBundleProvider.getValue("label.language"));
}
}
#MessageType("second")
public class SecondMessageHandler implements MessageHandler
{
#Override
public void processMessage(String inputMesssage)
{
System.out.println("SecondMessageHandler#processMessage: " + inputMesssage);
}
}
public class DefaultMessageHandler implements MessageHandler
{
#Override
public void processMessage(String inputMesssage)
{
System.out.println("DefaultMessageHandler#processMessage: " + inputMesssage);
}
}
I also have a class MessageDispatcher which uses reflections to scan the classpath for the annotated message handlers, instantiates them and puts them into a map:
#ApplicationScoped
public class MessageDispatcher
{
private Map<String, MessageHandler> messageHandlerMap = new HashMap<String, MessageHandler>();
#Inject
DefaultMessageHandler defaultMessageHandler;
public MessageDispatcher()
{
registerAnnotatedHandlers();
}
private void registerAnnotatedHandlers()
{
Reflections reflections = new Reflections("namespace");
try
{
for (Class<?> annotatedClass : reflections.getTypesAnnotatedWith(MessageType.class))
{
String annotationValue = annotatedClass.getAnnotation(MessageType.class).value();
for (Class<?> interfaceClass : annotatedClass.getInterfaces())
if (!annotationValue.isEmpty() && interfaceClass.equals(MessageHandler.class))
messageHandlerMap.put(annotationValue, (MessageHandler) annotatedClass.newInstance());
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
public MessageHandler getMessageHandler(String key)
{
MessageHandler messageHandler = messageHandlerMap.get(key);
return messageHandler != null ? messageHandler : defaultMessageHandler;
}
}
And finally in my websocket servlet's onMessage method I extract the key from the inbound message and use it for the message routing:
public synchronized void onMessage(String data)
{
String[] message = data.split(":");
// Choose the message handler from the message
MessageHandler messageHandler = messageDispatcher.getMessageHandler(message[0]);
// Process the message by the message handler
messageHandler.processMessage(message[1]);
}
My 3 incoming sample messages are:
"first:Message to handle with FirstMessageHandler"
"second:Message to handle with SecondMessageHandler"
"third:Message to handle with DefaultMessageHandler"
This works fine, The first and second messages are processed by FirstMessageHandler and SecondMessageHandler respectively. The third message is processed by the default message handler since there is no other handler registered for handling the key "third".
My Problem: I cannot use injection in the message handlers because they are created using Java reflection. Does anybody know how to get annotation processing and CDI injection 'married'? Or does anybody think this approach is bullshit and has another solution for that?
Best Regards
Sebastian
This is my final approach:
I spend a PostConstruct method to my MessageDispachter where I look for all message handler beans. For each of these beans I get their annotation value and a reference to the bean (which also includes creation of the bean). Then I store both, the annotation value and the bean reference into my messageHandlerMap. There is a lot of CDI delegating and interception involved, but it works:
public class MessageDispatcher
{
private Map<String, MessageHandler> messageHandlerMap = new HashMap<String, MessageHandler>();
#Inject
DefaultMessageHandler defaultMessageHandler;
#Inject
BeanManager beanManager;
#PostConstruct
public void registerHandlers()
{
Set<Bean<?>> messageHandlerBeans = beanManager.getBeans(MessageHandler.class, new MessageTypeLiteral());
for (Bean<?> bean : messageHandlerBeans)
{
String key = bean.getBeanClass().getAnnotation(MessageType.class).value();
if (!key.isEmpty())
{
CreationalContext<?> creationalContext = beanManager.createCreationalContext(bean);
MessageHandler messageHandler = (MessageHandler) beanManager.getReference(bean, MessageHandler.class, creationalContext);
messageHandlerMap.put(key, messageHandler);
}
}
}
public MessageHandler getMessageHandler(String key)
{
MessageHandler messageHandler = (MessageHandler) messageHandlerMap.get(key);
return messageHandler != null ? messageHandler : defaultMessageHandler;
}
}
#Documented
#Qualifier
#Retention(RUNTIME)
#Target({TYPE, METHOD, FIELD, PARAMETER})
public #interface MessageType
{
#Nonbinding
String value();
}
#SuppressWarnings("all")
public class MessageTypeLiteral extends AnnotationLiteral<MessageType> implements MessageType
{
private static final long serialVersionUID = 1L;
#Override
public String value()
{
return "";
}
}
public class DefaultMessageHandler implements MessageHandler
{
#Inject
ResourceBundleProvider resourceBundleProvider;
#Override
public void processMessage(String inputMesssage)
{
...
#MessageType("first")
public class FirstMessageHandler implements MessageHandler
{
#Inject
ResourceBundleProvider resourceBundleProvider;
#Override
public void processMessage(String inputMesssage)
{
...
The #NonBinding annotation in the #MessageType annotation seems to be important to find all beans annotated with #MessageType("xxx") independent of the actual annotation value (here: xxx).
I hope this explains the important things. For further details please ask me
Sebastian
I think your simplest solution to this would be to keep what you have, strip out the scanning because you don't need it, change your annotation to be a qualifier and fire a CDI event with the qualifier (you'll need to create an AnnotationLiteral for each of three different qualifiers because the value is binding) and the message as the payload.
I can explain more if you need it.
See and adjust Dynamically fire CDI event with qualifier with members
It is a CDI way for dynamic runtime selecting services by runtime decision. The TypeEnum can also be a String.
I'm new to CDI, tried searching for the usage, could not find anything and so posting the question. I'm trying to figure how I can inject an instance of a class with a parameterized constructor only using CDI. I'm not using Spring so, how it is done in spring does not help. Here is a sample I've created to show what's the issue. My #Inject will not work in this scenario.
public class A
{
public A(boolean deliverFromLocalWarehouse)
{
if(deliverFromLocalWarehouse)
{
wareHouseId = new Integer(10);
}
else
{
wareHouseId = new Integer(100);
}
}
public void deliver()
{
//get wareHouse address by Id and initiate delivery.
}
private Integer wareHouseId = null;
}
public class B
{
#Inject
private A a;
}
Thanks
Srikrishna Kalavacharla
If the constructor parameter should come from a bean, I think you can simply annotate it:
public A(#Inject boolean localWarehouse) { ...
and inject it with
#Inject A a;
If you want two different instances of A (with different constructor arguments), you could subclass them:
public AForLocalWarehouse extends A {
public AForLocalWarehouse() {
super(true);
}
}
and inject them with
#Inject AForLocalWarehouse a;
or use a producer method with qualifiers:
#Produces #LocalWarehouse
public A localWarehouse() { return new A(true); }
#Produces #RemoteWarehouse
public A remoteWarehouse() { return new A(false); }
and inject them with
#Inject #LocalWarehouse A a;
#Inject #RemoteWarehouse A a;