I have a method in an #Aspect service method called logChangesAndAnnounceNewContributions that fires whenever somewhere in the webapp the save method of Spring-data's JpaRepository is called. I don't want the logChanges method to be called when the save method is used within the Aspect class itself, so i used this in the pointcut definition !within(Services.SystemListenerService). But its not having any effect! The save method is still being called despite using this condition in the definition. The full definition looks like this:
#AfterReturning("execution(* org.springframework.data.jpa.repository.JpaRepository.save(..))" +
"&& !within(Services.SystemListenerService) && args(entity)")
private void logChangesAndAnnounceNewContributions(Object entity){
What am i missing here?
EDIT: I tried changing !within content to !within(#org.aspectj.lang.annotation.Aspect *) but that doesn't work either..
Assuming that Services.SystemListenerService is the fully qualified name of your aspect (class name SystemListenerService, package name Services with strange upper-case first letter), within() does not work because at the time of execution(* org.springframework.data.jpa.repository.JpaRepository.save(..)) we are not within(Services.SystemListenerService) anyway but rather within(org.springframework.data.jpa.repository.JpaRepository). So there is the logical error in your pointcut.
There are ways to solve this in AspectJ, such as
call(A) && !adviceexecution(),
execution(A) && !cflow(execution(B)),
but both pointcut types are unsupported in Spring AOP. So you
either need to activate full AspectJ via LTW in Spring
or abuse some Spring methods in order to get the real object underneath the proxy via ((Advised) myProxy).getTargetSource().getTarget() and call the method directly on that object from your aspect
or obtain a stack trace from a newly created exception or from the current thread and inspect it manually - very ugly.
Sorry, but Spring AOP is just "AOP lite", I think you should go for AspectJ. The second option is also a bit hacky but will probably work.
Related
We are using Autofac 4 for DI and I started experimenting with AI a short while ago. Now I created a IdentityTelemetryInitializer class which needs and IIdentityProvider to be able to get the ID of the current authorized user and set it add it to the context. I cannot find a way in which to inject dependencies into a TelemetryInitializer. If I define a contructor that takes an IIdentityProvider, the custom initializer is skipped altogether.
Any ideas are welcome. I was thinking of having the user ID also set as the Thread Principal so that we can access it this way, but I was hoping I could use DI for this?
You cannot inject dependencies using a constructor as the initializer initialized internally using the default (empty) constructor. When you explicitly defined a new ctor you've actually 'removed' the default one, thus the initializer was skipped altogether, as you've mentioned.
Therefore, the only way is to resolve the dependencies during the 'Initialize' method, after registering them on application startup.
ctx.RegisterType<MyService>().As<IService>().AsSelf(); // on application startup
ctx.Resolve<IService>(); // during initializer 'Initialize' method
You might look at the question I asked here
How to have "Request" events with authenticated user id ?
because I had managed to have the TelemetryInitializer working, passing user id via the HttpContext as suggested by #yonisha.
Off course it's not as lean as what you try to achieve.
The Telemetry Initializer is called each time you instanciate a Telemetry class, so really depending of how you manage them. Btw I am looking for good advice/best pratice on that : for the moment I have one private instance on each Controller that need to track something, but that does not smell good due to lifetime of Controller.
Hi I am trying to learn JAVA deeply and so I am digging into the JDK source code in the following lines:
URL url = new URL("http://www.google.com");
URLConnection tmpConn = url.openConnection();
I attached the source code and set the breakpoint at the second line and stepped into the code. I can see the code flow is: URL.openConnection() -> sun.net.www.protocol.http.Handler.openConnection()
I have two questions about this
First In URL.openConnection() the code is:
public URLConnection openConnection() throws java.io.IOException {
return handler.openConnection(this);
}
handler is an object of URLStreamHandler, define as blow
transient URLStreamHandler handler;
But URLStreamHandler is a abstract class and method openConnection() is not implement in it so when handler calls this method, it should go to find a subclass who implement this method, right? But there are a lot classes who implement this methods in sun.net.www.protocol (like http.Hanlder, ftp.Handler ) How should the code know which "openConnection" method it should call? In this example, this handler.openConnection() will go into http.Handler and it is correct. (if I set the url as ftp://www.google.com, it will go into ftp.Handler) I cannot understand the mechanism.
second. I have attached the source code so I can step into the JDK and see the variables but for many classes like sun.net.www.protocol.http.Handler, there are not source code in src.zip. I googled this class and there is source code online I can get but why they did not put it (and many other classes) in the src.zip? Where can I find a comprehensive version of source code?
Thanks!
First the easy part:
... I googled this class and there is source code online I can get but why they did not put it (and many other classes) in the src.zip?
Two reasons:
In the old days when the Java code base was proprietary, this was treated as secret-ish ... and not included in the src.zip. When they relicensed Java 6 under the GPL, they didn't bother to change this. (Don't know why. Ask Oracle.)
Because any code in the sun.* tree is officially "an implementation detail subject to change without notice". If they provided the code directly, it helps customers to ignore that advice. That could lead to more friction / bad press when customer code breaks as a result on an unannounced change to sun.* code.
Where can I find a comprehensive version of source code?
You can find it in the OpenJDK 6 / 7 / 8 repositories and associated download bundles:
http://hg.openjdk.java.net/jdk6/jdk6 - http://download.java.net/openjdk/jdk6/
http://hg.openjdk.java.net/jdk7/jdk7 - http://download.java.net/openjdk/jdk7/
http://hg.openjdk.java.net/jdk8/jdk8
Now for the part about "learning Java deeply".
First, I think you are probably going about this learning in a "suboptimal" fashion. Rather than reading the Java class library, I think you should be reading books on java and design patterns and writing code for yourself.
To the specifics:
But URLStreamHandler is a abstract class and method openConnection() is not implement in it so when handler calls this method, it should go to find a subclass who implement this method, right?
At the point that the handler calls than method, it is calling it on an instance of the subclass. So finding the right method is handled by the JVM ... just like any other polymorphic dispatch.
The tricky part is how you got the instance of the sun.net.www.protocol.* handler class. And that happens something like this:
When a URL object is created, it calls getURLStreamHandler(protocol) to obtain a handler instance.
The code for this method looks to see if the handler instance for the protocol already exists and returns that if it does.
Otherwise, it sees if a protocol handler factory exists, and if it does it uses that to create the handler instance. (The protocol handler factory object can be set by an application.)
Otherwise, searches a configurable list of Java packages to find a class whose FQN is package + "." + protocol + "." + "Handler", loads it, and uses reflection to create an instance. (Configuration is via a System property.)
The reference to handler is stored in the URL's handler field, and the URL construction continues.
So, later on, when you call openConnection() on the URL object, the method uses the Handler instance that is specific to the protocol of the URL to create the connection object.
The purpose of this complicated process is to support URL connections for an open-ended set of protocols, to allow applications to provide handlers for new protocols, and to substitute their own handlers for existing protocols, both statically and dynamically. (And the code is more complicated than I've described above because it has to cope with multiple threads.)
This is making use of a number of design patterns (Caches, Adapters, Factory Objects, and so on) together with Java specific stuff such as the system properties and reflection. But if you haven't read about and understood those design patterns, etcetera, you are unlikely to recognize them, and as a result you are likely to find the code totally bamboozling. Hence my advice above: learn the basics first!!
Take a look at URL.java. openConnection uses the URLStreamHandler that was previously set in the URL object itself.
The constructor calls getURLStreamHandler, which generates a class name dynamically and loads, and the instantiates, the appropriate class with the class loader.
But URLStreamHandler is a abstract class and method openConnection()
is not implement in it so when handler calls this method, it should go
to find a subclass who implement this method, right?
It has to be declared or abstract or implemented in URLStreamHandler. If you then give an instance of a class that extends URLStreamHandler with type URLStreamHandler and call the openConnection() method, it will call the one you have overriden in the instance of the class that extends URLStreamHandler if any, if none it will try to call the one in URLStreamHandler if implemented and else it will probably throw an exception or something.
I've been going through the documentation for creating Prism applications and setting up the Shell seems to be split into 2 methods, CreateShell() and InitializeShell()
For CreateShell I simply have:
protected override DependencyObject CreateShell()
{
return ServiceLocator.Current.GetInstance<Shell>();
}
The documentation says that code is needed in the IntializeShell() method to ensure it is ready to be displayed. The following is given as an example:
protected override void InitializeShell()
{
Application.Current.MainWindow = (Window)this.Shell;
Application.Current.MainWindow.Show();
}
I have noticed however that if I omit the first line and just call the Show() method it seems to work (MainWindow already appears to have Shell assigned to it). Can you tell me why this is the case, and why we still need to explicity set the MainWindow property here?
Also as I did not specifically register Shell to an interface within the container, how is it able to resolve Shell in CreateShell()?
Question 1: Why does just calling Show() seem to work and why is Application.Current.MainWindow seem to be populated?
There are a few things you should check here. In a typical WPF application, the type for the main window can be specified in the App.xaml. If it is specified, WPF will instantiate one of those for you. This is not desirable because WPF won't use your container to instantiate your shell and any dependencies won't be resolved.
When you run that first line of code in InitializeShell, you'd be replacing the WPF-instantiated Shell object with the one you manually instantiated.
I looked at the code for the MEF and Unity bootstrappers and I don't see anywhere that MainWindow is being set, but I don't know if you might have customized the base bootstrappers, so that's something else to look for.
Show() works because you are simply showing the window you instantiated and the WPF-instantiated one isn't shown. This is my theory, but without seeing your code, it'd be tough to say for sure.
Question 2: How can Unity resolve something that hasn't been registered?
Unity can always resolve a concrete type, regardless of registration. It cannot resolve non-concrete classes that haven't been mapped to a concrete type. This is why Resolve<Shell> works, but Resolve<IMyInterface> doesn't unless you register a type.
By my (likely meager) understanding, doing this in the middle of a method in your controller / presenter is considered bad practice, since it creates a dependency between StructureMap and your presenter:
void Override() {
ICommentForOverrideGetter comm = StructureMap.ObjectFactory.GetInstance<ICommentForOverrideGetter>();
since this dependancy should be injected into the presenter via the constructor, with your IoC container wiring it up. In this case though my code needs a fresh copy of ICommentForOverrideGetter every time this method runs. Is this an exception to the above best practice, or a case where I should re-think my architecture?
It is said that there is no problem in computer science which cannot be solved by one more level of indirection:
If you just don't want the dependency in your presenter, inject a factory interface, the real implementation could do new CommentForOverrideGetter or whatever.
Edit:
"I have no problem ignoring best practices when I think the complexity/benefit ratio is too high": Neither do I, but as I said in the comments, I don't like hard dependencies on IoC containers in code I want to unit test and presenters are such a case.
Depending on what your ICommentForOverrideGetter does, you could also use a simple CommentForOverrideGetter.CreateNew() but as you require a fresh instance per call, I'd suspect at least some kind of logic associated with the creation? Or is it a stateful "service"?
If you insist on doing service location in your method, you should at least inject the container into your controller, so that you can eliminate the static method call. Add a constructor parameter of type StructureMap.IContainer and store it in a field variable. StructureMap will inject the proper container. You can then call GetInstance() on that container, instead of ObjectFactory.
I use contructor injection in my solution, but this one class has a property that i do not want to pass in the constructor where i have the invariant dependencies.
Let's say i got an ILogger and it has a FileName property i want to set, while still having it set the dependancies in the contructor.
How do i go about registering the type, and at the same time pass the defaunt connection string.
I hope there is an easy way to do it - preferably without decorating the property with an attribute, but if the setup is easier with the attribute i guess that's cool :)
So the question is, how do i inject a property value on an object that also uses contructor injection - with Unity.
UPDATE: I mentioned it in the title, but i forgot to elaborate in the body of the text - i want to set these dependencies up manually (in code) as opposed to in a config file.
Ok i guess it helped to ask the question, i found out - here it is.
container.Configure<InjectedMembers>().ConfigureInjectionFor<BasicLogger>(
new InjectionProperty("FileName", #"C:\test.log")
);
If you are injecting properties you have to use [Dependency] or else manually inject that dependency.
You usually want an IConfiguration interface to be injected. This would probably have a LogFile property that you can read.
The Configuration implimentation is usually just a simple wrapper to read items from the config file.