As I already have application.properties, where the database connection settings are defined, I decided it is good to put my application-specific settings in that file too. A step further - as spring reads those properties, I declared my Settings bean as follows
<bean name="settingsBean" class="com.tickets.constants.Settings">
<property name="settings">
<props>
<prop key="backup.dir">${backup.dir}</prop>
<prop key="smtp.host">${smtp.host}</prop>
</props>
<property>
</bean>
Now, it happens sometimes, that I need some of those properties in classes that aren't directly in the spring context. Yes - I can either get the spring context from my web application context, or pass the settings as a method parameter to the utility classes, but here's my alternative approach (this is the Settings class):
private static Properties staticSettings;
#PostConstruct
public void init() {
// making the settings available for static access
staticSettings = settings;
}
Now, this looks a bit wrong. But I can't think of a strong reason for not using it.
So to formulate the question - is there any reason not to use my approach, and is there a better one.
You're right, your solution "feels" wrong - the interaction of statics and instance looks like an anti-pattern, but it's a bit of a slippery one to get a grip on.
My gut feeling would be to push the statics a bit further, and make the class itself more internally-consistent, without sacrificing the Spring integration:
public class Settings {
private static Settings instance;
public static Settings initialise(Properties settings) {
instance = new Settings(settings);
return instance;
}
public static Settings get() {
return instance;
}
private final Properties settings;
private Settings(Properties settings) {
this.settings = settings;
}
public String getProperty(String key) {
return settings.getProperty(key);
}
}
Your Spring config would then use factory-method="initialise" rather than the constructor, and other code can use the static get() method to retrieve the singleton. You avoid duplication of the Properties object, and while the static singleton is a bit of an anti-pattern itself, the code makes rather more sense.
But that's the best I can come up with on a freezing cold Saturday morning :)
This is a good question, and I hope you get several informed and well-reasoned responses (better than the one I expect I'm writing).
The reasons for not using this approach are the same as for adopting the Spring framework in the first place: inversion of control, loose coupling, etc. That said, I feel that if you've considered those points in this context and nevertheless feel that this approach elegantly satisfies your actual needs, go right ahead.
Sometimes I feel that Spring -- indeed many leading frameworks & techniques -- allow themselves to slip into "my way or the highway" API design, where the only way to overcome the limitations of Spring is with more Spring.
It shouldn't be that way. You should be able to adopt a thing like Spring in an existing project without signing up to re-architect every bit of your app.
And in fact there are 365236 ways (yours in one) to share objects between the Spring and non-Spring worlds. There's no technical limitation; but the zealots will give you grief.
Related
I am trying to create a generic Logger which would be a small standalone code. Different applications can use this Logger for logging.
Let's say, there are two different codebases- CB1 and CB2.
CB1 needs to capture all public methods of all classes under package- CB1/a/b/c
CB2 needs to capture all public methods of all classes under package- CB2/d/e/f
Now, what I have done till now is as below-
A new codebase, say LogUtility which has an Aspect GenericLogger-
public class GenericLogger {
public Object aroundLog(ProceedingJoinPoint jp) {
//logging code goes here
}
}
in some_context.xml-
<aop:config>
<aop:aspect id="loggerAspect" ref="myLogger">
<aop:pointcut id="sample" expression="${logger.pointcutExpr}" />
<aop:around method="aroundLog" pointcut-ref="sample" />
</aop:aspect>
</aop:config>
If CB1 needs to use this LogUtility, CB1 will add LogUtility to its pom/ivy dependency and provide the value of ${logger.pointcutExpr} via a property file at application startup time.
So, it works fine this way for CB1, CB2,...
The only disadvantage of this approach that I think is the long list in the properties file which has the single key i.e.logger.pointcutExpr
Good thing is, whenever any codebase needs to change it can just add a new pointcut in its own properties file. So a single Aspect can serve multiple codebases.
Earlier, I was trying to do something like this,
#Aspect
#Component
public class GenericLogger {
#Around(<can't make this dynamic>)
public object aroundLog(ProceedingJoinPoint jp) {
//logging code goes here
}
}
The problem with the above is that values passed to any annotation must be final, so can't go with this approach.
I was wondering if there is anything that can be done to achieve this on the fly.
1. Any way in which different codebases can provide the value of the key logger.pointcutExpr without explicitly creating a properties file.
2. Or is it possible to register pointcut with an Aspect on the fly?
I've been googling a lot on this and I'm finding basic AOP tutorials everywhere. I think to do something like this I need to dig deeper in AspectJ along with Spring AOP. I found below links-
https://docs.spring.io/spring/docs/3.0.x/spring-framework-reference/html/aop.html#aop-choosing
how to apply spring aop for legacy code by taking pointcut as input from user
https://eclipse.org/aspectj/doc/next/devguide/ltw-configuration.html
I have basic knowledge of AspectJ, what I'm looking for could be silly.
You can make what is in the Around method dynamic (sort of) by using a static final expression.
But I would suggest something else.
You can definitely do this sort of thing in AspectJ, it's just that you will need to firstly think of the Aspect as describing what expression will execute for the super set of all your cases. Then within the aspect define the behaviour you are wanting to achieve. So for instance you can use Object target = joinPoint.getTarget(); to get the target (class which was executing the method), and then use String canonicalName = taget.getCanonicalName() which will include the package in the name, and then you can do stuff like:
if(getCanonicalName.contains("some/package") {
System.out.println("You can do better than this if statement");
}
And make whatever if statements you need to differentiate between the various packages which are contained in the canonical name. That way you can have greater control over what happens for each package.
I have written some code which I thought was quite well-designed, but then I started writing unit tests for it and stopped being so sure.
It turned out that in order to write some reasonable unit tests, I need to change some of my variables access modifiers from private to default, i.e. expose them (only within a package, but still...).
Here is some rough overview of my code in question. There is supposed to be some sort of address validation framework, that enables address validation by different means, e.g. validate them by some external webservice or by data in DB, or by any other source. So I have a notion of Module, which is just this: a separate way to validate addresses. I have an interface:
interface Module {
public void init(InitParams params);
public ValidationResponse validate(Address address);
}
There is some sort of factory, that based on a request or session state chooses a proper module:
class ModuleFactory {
Module selectModule(HttpRequest request) {
Module module = chooseModule(request);// analyze request and choose a module
module.init(createInitParams(request)); // init module
return module;
}
}
And then, I have written a Module that uses some external webservice for validation, and implemented it like that:
WebServiceModule {
private WebServiceFacade webservice;
public void init(InitParams params) {
webservice = new WebServiceFacade(createParamsForFacade(params));
}
public ValidationResponse validate(Address address) {
WebService wsResponse = webservice.validate(address);
ValidationResponse reponse = proccessWsResponse(wsResponse);
return response;
}
}
So basically I have this WebServiceFacade which is a wrapper over external web service, and my module calls this facade, processes its response and returns some framework-standard response.
I want to test if WebServiceModule processes reponses from external web service correctly. Obviously, I can't call real web service in unit tests, so I'm mocking it. But then again, in order for the module to use my mocked web service, the field webservice must be accessible from the outside. It breaks my design and I wonder if there is anything I could do about it. Obviously, the facade cannot be passed in init parameters, because ModuleFactory does not and should not know that it is needed.
I have read that dependency injection might be the answer to such problems, but I can't see how? I have not used any DI frameworks before, like Guice, so I don't know if it could be easily used in this situation. But maybe it could?
Or maybe I should just change my design?
Or screw it and make this unfortunate field package private (but leaving a sad comment like // default visibility to allow testing (oh well...) doesn't feel right)?
Bah! While I was writing this, it occurred to me, that I could create a WebServiceProcessor which takes a WebServiceFacade as a constructor argument and then test just the WebServiceProcessor. This would be one of the solutions to my problem. What do you think about it? I have one problem with that, because then my WebServiceModule would be sort of useless, just delegating all its work to another components, I would say: one layer of abstraction too far.
Yes, your design is wrong. You should do dependency injection instead of new ... inside your class (which is also called "hardcoded dependency"). Inability to easily write a test is a perfect indicator of a wrong design (read about "Listen to your tests" paradigm in Growing Object-Oriented Software Guided by Tests).
BTW, using reflection or dependency breaking framework like PowerMock is a very bad practice in this case and should be your last resort.
I agree with what yegor256 said and would like to suggest that the reason why you ended up in this situation is that you have assigned multiple responsibilities to your modules: creation and validation. This goes against the Single responsibility principle and effectively limits your ability to test creation separately from validation.
Consider constraining the responsibility of your "modules" to creation alone. When they only have this responsibility, the naming can be improved as well:
interface ValidatorFactory {
public Validator createValidator(InitParams params);
}
The validation interface becomes separate:
interface Validator {
public ValidationResponse validate(Address address);
}
You can then start by implementing the factory:
class WebServiceValidatorFactory implements ValidatorFactory {
public Validator createValidator(InitParams params) {
return new WebServiceValidator(new ProdWebServiceFacade(createParamsForFacade(params)));
}
}
This factory code becomes hard to unit-test, since it is explicitly referencing prod code, so keep this impl very concise. Put any logic (like createParamsForFacade) on the side, so that you can test it separately.
The web service validator itself only gets the responsibility of validation, and takes in the façade as a dependency, following the Inversion of Control (IoC) principle:
class WebServiceValidator implements Validator {
private final WebServiceFacade facade;
public WebServiceValidator(WebServiceFacade facade) {
this.facade = facade;
}
public ValidationResponse validate(Address address) {
WebService wsResponse = webservice.validate(address);
ValidationResponse reponse = proccessWsResponse(wsResponse);
return response;
}
}
Since WebServiceValidator is not controlling the creation of its dependencies anymore, testing becomes a breeze:
#Test
public void aTest() {
WebServiceValidator validator = new WebServiceValidator(new MockWebServiceFacade());
...
}
This way you have effectively inverted the control of the creation of the dependencies: Inversion of Control (IoC)!
Oh, and by the way, write your tests first. This way you will naturally gravitate towards a testable solution, which is usually also the best design. I think that this is due to the fact that testing requires modularity, and modularity is coincidentally the hallmark of good design.
I am currently using the Owasp ESAPI to manage authentication in my java web application, and I am injecting the Singleton MyAuthenticator with guice.injectMembers(this). I would like to step away from this approach and use a guice-created Singleton-Scoped object. I liked the thread-safety of the ESAPI singleton, and the safety of singletons in general, using Double-Checked Locking, IODH Idiom, or Bloch's Enum INSTANCE style.
What do I need to do to my Guicified Singleton-Scoped Authenticator to make it thread-safe, as well as the ThreadLocal field I am using to get and set my current User?
I would like to make the entire application work with dependency-injection, but don't want it to break upon web-app concurrent access. Any suggestions or common pitfalls?
The ThreadLocal object I am using looks like the code below:
private final ThreadLocalUser currentUser = new ThreadLocalUser();
private class ThreadLocalUser extends InheritableThreadLocal<User> {
#Override
public User initialValue() {
return User.ANONYMOUS;
}
public User getUser() {
return super.get();
}
public void setUser(User newUser) {
super.set(newUser);
}
}
Unfortunately I don't know enough about Owasp ESAPI to give a specific answer, but you may have some luck looking into Guice's AOP support. You can intercept all method invocations on the class and provide whatever concurrency behavior you like.
http://code.google.com/p/google-guice/wiki/AOP
Beware using the "Double-Check Locking" pattern in Java. This design pattern doesn't reliably work in Java (for instance, see http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html) unless you declare the singleton instance as "volatile".
Hard to think of a title for this one! I have a bean that is initialized in a spring container. It loads classes that also create objects from files using Spring classloaders. Some of these objects may have dependencies on expensive objects and I would like those objects to be initialized in the parent. Okay I can't explain in words so on to a simplified example:
public class MainLoader {
public static void main(String[] args) {
XmlBeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("top-context.xml"));
ChildLoader childLoader = (ChildLoader)beanFactory.getBean("childLoader");
childLoader.loadChildAndDoSomething("message1.xml");
childLoader.loadChildAndDoSomething("message2.xml");
}
}
public class ChildLoader {
public void loadChildAndDoSomething(String childContextfile){
XmlBeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource(childContextfile));
ClassThatDoesStuff classThatDoesStuff = (ClassThatDoesStuff)beanFactory.getBean("classThatDoesStuff");
classThatDoesStuff.saySomething();
}
}
public class ClassThatDoesStuff {
private ReallyExpensiveService reallyExpensiveService;
private String messageStart;
public void saySomething(){
System.out.println(messageStart + reallyExpensiveService.getName());
}
// .. field setters removed for brevity
}
public class ReallyExpensiveService {
public String getName(){
return "Joe";
}
}
These have the following beans in the files:
top-context.xml:
<bean id="childLoader" class="com.mark.test.ChildLoader" />
message1.xml (message2.xml is similar):
<bean id="classThatDoesStuff" class="com.mark.test.ClassThatDoesStuff">
<property name="messageStart" value = "Hello! " />
<property name ="reallyExpensiveService" ref="theExpensiveserviceReference" />
</bean>
<bean id="theExpensiveserviceReference" class="com.mark.test.ReallyExpensiveService" />
When these are run you get the expected:
Hello! Joe
Goodbye! Joe
The only problem here is that the "ReallyExpensiveService" is getting created and cached by Spring on each occasion. This is verified by the log. Better to load up any services that might be needed by the "ClassThatDoesStuff" classes (imagine it's an interface) when the MainLoader is initialzed. I.e. (conceptually) change the spring context files to:
top-context.xml:
<bean id="childLoader" class="com.mark.test.ChildLoader" />
<bean id="theExpensiveserviceReference" class="com.mark.test.ReallyExpensiveService" />
message1/2.xml
<bean id="classThatDoesStuff" class="com.mark.test.ClassThatDoesStuff"
autoWired="byType">
<property name="messageStart" value = "Hello! " />
</bean>
I realise that the way out of this would be to have the ClassThatDoeStuff have a setter for the service and set the value from the Child container which itself had it injected via the main context. But imagine that there are arbitrary services and each of the ClassThatDoesStuff implementers used different ones.. Is there any way for this to work in Spring..?
It seems like the best you can hope for is to instantiate each ReallyExpensiveService one time. (You mention in there that you're not sure which ClassThatDoesStuff may use a different one.) I would probably try to define all of my ReallyExpensiveService beans in the top level context and then hand them out to the classes that use them wherever it's appropriate, either through the XML configuration files that you're using or through some kind of factory that you inject into the ClassThatDoesStuff beans.
You might also try to look for a way to defer the expensive operations of starting up ReallyExpensiveService until you're sure they're going to be used. Of course this depends on what "expensive" means. Is it that the services use too much memory and you don't want them around if they're not in use or that they take too long to instantiate?
In any case, the key here is to have as few instances of expensive things floating around as possible, so you'll want to configure them at the top level so that the references to the single instances can be passed around anywhere.
I fiddled around a lot with this and learnt a lot about spring in the process. I don't think it's possible to get the parent spring context to apply these properties dynamically. I got around the problem by implementing caching in the mainloader object so that expensive types aren't created multiple times frmo the spring definition.
The other possiblity I investigated was making the ChildLoader context aware and allowing the ClassThatDoesStuff to use the parent context to get handles on beans, but this was bedding in spring to the app too much for my liking.
My spaghetti monster consumes XML from several different SOAP services, and the URL for each service is hardcoded into the application. I'm in the process of undoing this hardcoding, and storing the URLs in a properties file.
In terms of reading the properties file, I'd like to encompass that logic in a Singleton that can be referenced as needed.
Change this:
accountLookupURL ="http://prodServer:8080/accountLookupService";
To this:
accountLookupURL =urlLister.getURL("accountLookup");
The Singleton would be contained within the urlLister.
I've tended to shy away from the Singleton pattern, only because I've not had to use it, previously. Am I on the right track, here?
Thanks!
IVR Avenger
You haven't said why you need only one of whatever it is which will be getting the URL. If that just involves reading a properties file, I don't think you do need only one. Seems to me that having two threads read the same properties file at the same time isn't a problem at all.
Unless you were thinking of having some object which only reads the properties file once and then caches the contents for future use. But this is a web application, right? So the way to deal with that is to read in the properties when the application starts up, and store them in the application context. There's only one application context, so there's your "only one" object.
As an alternative, did you consider using something like Apache Commons Configuration (or maybe another configuration framework)?
Singletons are appropriate for this scenario, BUT you have to make sure you're doing the singleton right.
So, for example, what Bozhno suggests is not a singleton, it's an ugly concoction of nasty statics that's not mockable, not easily testable, not injectable, and generally comes back to bite you in the ass.
An acceptable singleton is just your average class with one notable exception that it is guaranteed either by itself or by some external factory/framework (e.g Spring IoC) to exist in only one instance. If you go with the first approach, you do something like
private MyUberSingletonClass() {
//..do your constructor stuff, note it's private
}
private static MyUberSingletonClass instance = null;
public static synchronized MyUberSingletonClass instance() {
if (instance == null) {
instance = new MyUberSingletonClass();
}
return instance;
}
public String getUberUsefulStuff(){
return "42";
}
That's acceptable if you don't really feel the need for a factory otherwise, and aren't using any IoC container in your app (good idea to think about using one though). Note the difference from Bozhno's example: this is a good vanilla class where the only static is an instance var and a method to return it. Also note the synchronized keyword required for lazy-initialization.
update: Pascal recommends this very cool post about a better way to lazy-init singletons in the comments below: http://crazybob.org/2007/01/lazy-loading-singletons.html
Based on your suggestions, and the fact that I don't think I have as much access to this application as I'd hoped (a lot of it is abstracted away in compiled code), here's the solution I've cooked up. This is, of course, a stub, and needs to be fleshed out with better exception handling and the like.
public class WebServiceURLs {
private static class WebServiceURLsHolder
{
public static WebServiceURLs webServiceURLs = new WebServiceURLs();
}
private Properties webServiceURLs;
public WebServiceURLs()
{
try
{
Properties newURLProperties = new Properties();
InputStreamReader inputStream = new InputStreamReader(
FileLoader.class.getClassLoader().getResourceAsStream("../../config/URLs.properties") );
newURLProperties.load(inputStream);
webServiceURLs =newURLProperties;
}
catch (Exception e)
{
webServiceURLs =null;
}
}
public String getURLFromKey(String urlKey)
{
if (webServiceURLs==null)
return null;
else
return webServiceURLs.getProperty(urlKey);
}
public static WebServiceURLs getInstance()
{
return WebServiceURLsHolder.webServiceURLs;
}
}
Is this a good effort as my "first" Singleton?
Thanks,
IVR Avenger
To restate the obvious, Singleton is to be used when all client code should talk to a single instance of the class. So, use a Singleton IFF you are certain that you would not want to load multiple properties files at once. Personally, I would want to be able to have that functionality (loading multiple properties files).
Singletons are mutable statics and therefore evil. (Assuming a reasonably useful definition of "singleton".
Any code that uses the static (a transitive relationship), is has assumptions about pretty much everything else (in this case, a web server and the internet). Mutable statics are bad design, and bad design makes many aspects go rotten (dependency, understandability, testing, security, etc).
As an example, the only thing stopping late versions of JUnit 3 being used in a sandbox was loading a configuration file in one static initialiser. If it had used Parameterisation from Above, there would have been no issue.