Reputation: 29322
Is it possible to customise the code for a JAXWS class. What I want to do is add some helper methods to the generated class to help extract information from it. I know I can subclass the generated source but this means I have to cast it everywhere I want the info.
Is it possible to have jaxws (or another tool) merge together the generated source code from the WSDL with some custom code containing my methods? (In C# I could do this with a partial class but java doesn't appear to have an equivalent)...
Upvotes: 4
Views: 1096
Reputation: 2959
There are many ways to do this, one of them which is using aspect is already mentioned by another answer.
I would like to suggest a lighter alternative, which is to just extend the generated class:
public GeneratedClass {
public void doThis();
}
public ImprovedClass extends GeneratedClass {
public void doExtraStuff();
}
The advantage of this is that you have a clear definition of that GeneratedClass can do. If you start weaving methods into the GeneratedClass, the one who work on the project a few years later on might get the idea that all similar instance of the generated class have the same method. Or they might be confused why some generated classes have these extra methods, and some not. The extra functionality should be kept in a clearly defined class. Only the subclass of that type can do the extra stuff. This makes it clear where the method comes from.
It's not like I have something against code weaving, but I think code weaving should only be used for something that doesn't involve business logic like logs, metrics, or for inside a framework. Business logic related code should not be weaved to a class.
Anyway, another way to do this is to wrap the class, but this will need an interface.
public GeneratedClass implements SomeInterface {
public void doThis();
}
public ImprovedClass implements SomeInterface {
public SomeInterface impl;
public Improvedclass(SomeInterface impl) {
this.impl = impl;
}
public void doThis() {
this.impl.doThis();
}
public void doExtraStuff() {
// the extra stuff
}
}
Upvotes: 1
Reputation: 217274
One approach to achieve this would be to introduce those helper methods via aspects. AspectJ would be a potential candidate for this, or if you're using Spring, then Spring AOP could also do the job.
So using AspectJ, you'd leverage the feature called "inter-type declaration", which allows one to introduce new features into existing classes. If your generated JAXWS class is called MyTypeGen
, then you'd introduce new methods using an aspect (arbitrarily named MyTypeAspect
) like this:
// generated class
class MyTypeGen {
int x, y;
public void setX(int x) { this.x = x; }
public void setY(int y) { this.y = y; }
}
// introduce two new methods into MyTypeGen
aspect MyTypeAspect {
public int MyTypeGen.multiply() {
return x * y;
}
public int MyTypeGen.sum() {
return x + y;
}
}
At runtime, you can call those two new methods which have been weaved into MyTypeGen
at build-time. No casting needed.
MyTypeGen mytype = new MyTypeGen();
mytype.setX(3);
mytype.setY(4);
int product = mytype.multiply();
// product = 12
If you decide to use Spring AOP instead, you'd create a normal Java class with the @Aspect
annotation, in which you'd leverage the introductions feature.
Upvotes: 4