tags:

views:

205

answers:

1

I need only a single instance of Twitter class in Twitter4j in my Spring container. My problem is that I can see no way to set the oauth consumer in the Twitter class. As I far as I know,you can only wire using a setter method which only takes in one parameter. Not two. For example there is think there is no way I can wire something like this:

Twitter twitter = new Twitter();
twitter.setOAuthConsumer([consumer key],[consumer secret]);

Of course I want to avoid hard-coding the consumer key and consumer secret that defeats using D.I I guess.

My solution is to encapsulate the twitter class in another class so I can wire the consumer key and consumer secret one by one:

public class TwitterAuth {
    private Twitter twitter;
    public TwitterAuth(Twitter twitter, consumerKey, consumerSecret) {
      this.twitter=twitter;
      twitter.setOauthConsumer(consumerKey,consumerSecret);
    }
    public void getTwitter(){
       return twitter;
    }
}

Although it does solve my problem, it presents me with another one. I don't need the TwitterAuth anymore once the twitter class is injected. How do I discard the TwitterAuth?

Better yet is there a better way to wire this? Thanks! :)

+2  A: 

I don't need the TwitterAuth anymore once the twitter class is injected. How do I discard the TwitterAuth?

I wouldn't worry about discarding TwitterAuth. Once there are no references to it, it will be garbage collected eventually. Either way, it doesn't have a large memory footprint.

You don't need to have your code depend on TwiterAuth. Instead, you can tell Spring to create the Twitter object using an instance factory method. First you will need to make a slight modification to TwitterAuth so that it creates the Twitter object:

public class TwitterAuth {
    private final Twitter twitter;
    public TwitterAuth(String consumerKey, String consumerSecret) {
      this.twitter = new Twitter();
      twitter.setOauthConsumer(consumerKey, consumerSecret);
    }
    public Twitter getTwitter() {
       return twitter;
    }
}

If the bean name for TwitterAuth is "twitterAuth", then this XML will configure TwitterAuth.getTwitter() as a factory method:

<bean id="twitter"
      factory-bean="twitterAuth"
      factory-method="getTwitter"/>

Then you can inject the Twitter object into your classes directly, instead of having the classes depend on TwitterAuth. Constructor and setter injection for TwitterAuth will be done before Spring calls the getTwitter() method.

Instead of using an instance factory method, you can change TwitterAuth to implement FactoryBean. The advantage is a bit less XML. The disadvantage is Java source code would be more tied to Spring.

NamshubWriter
I liked this answer but I am confused at what I want to have right now. I realized by making a TwitterAuth class I was adding a factory to my app. I stumbled upon the MethodInvokingFactoryBean before reading your reply. The way I see it I don't need to have a TwitterAuth just the twitter class and then I'd just wire the method to invoke plus the arguments. Right now though I can't figure how to inject something like that into the other beans that need it. And using the MethodInvokingFactoryBean doesn't look very readable to me (well maybe because I don't know how to use it).
Jeune
I tried to play around with the MethodInvokingFactoryBean, it didn't work out. I am going with yer suggestion. Cheers! and Thanks!
Jeune
MethodInvokingFactoryBean would work if you had a static method that took in the consumerKey and consumerSecret and returned a Twitter object. The XML would be very similar to the second example here: http://static.springsource.org/spring/docs/2.0.x/api/org/springframework/beans/factory/config/MethodInvokingFactoryBean.html
NamshubWriter