Once when pointcuts and advices are defined, it is easy to define a proxy aspect itself:
ProxyAspect aspect = new ProxyAspect(LogProxyAdvice.class, pointcut);
There are several ways how to create proxified class (or its instance) using Proxetta:
byte[] fooBytes = Proxetta.withAspects(aspect).createProxy(Foo.class); Class fooClass = ClassLoaderUtil.defineClass(fooBytes)
or, at once:
Class fooClass = Proxetta.withAspects(aspect).defineProxy(Foo.class);
or, directly an instance:
Foo foo = Proxetta.withAspects(aspect).createProxyInstance(Foo.class);
These are just basic Proxetta usages, there are more inside. It is possible to provide target class with its string name or input stream. Moreover, by default, creating proxy on target class still doesn't means that proxy will be created for class methods - if class has no pointcuts it will remain untouched (this feature is configurable). It is possible to configure Proxetta to create variable proxy class names, so proxy may be created several times and loaded by same class loader without problem. And so on...
By default, proxy name is created from target class name, by appending default suffix. Suffix name can be changed. Moreover, if variable names feature is turned on, added suffix is changed each time by appending auto-incrementing number. In all cases, proxy class is in the same package as target class.
Sometimes it is needed to have more control over proxy class name and package. This is especially important when proxyfing JDK classes, since default classloader doesn't allow to instantiate anything from java.* package.
Proxetta allows to completely control proxy names. Every method for proxy definition and proxy creation accept second argument that defines proxy name in the following ways:
.Foo (class name starts with a dot) - proxy package name is equal to target package, just proxy simple class name is set.foo. (class name ends with a dot) - proxy package is set, proxy simple name is create from target simple class name (suffix is appended).foo.Foo - full proxy class name is specified (suffix is appended).Adding suffix can be also completely disabled, but in that case different package for proxy class must be provided, since it is not possible to define two classes with the same package and simple names.
It is easy to apply aspects on beans registered in the Petite container transparently. Petite has single point method for beans registration. User may override this method and create proxy for each bean type before it is actually registered in the container:
public class MyPetiteContainer extends PetiteContainer {
protected final Proxetta proxetta;
public MyPetiteContainer(Proxetta proxetta) {
this.proxetta = proxetta;
}
@Override
protected BeanDefinition registerPetiteBean(String name, Class type, Class<? extends Scope> scopeType, WiringMode wiringMode) {
if (name == null) {
name = PetiteUtil.resolveBeanName(type);
}
type = proxetta.defineProxy(type);
return super.registerPetiteBean(name, type, scopeType, wiringMode);
}
}
Attention with bean name: since Proxetta modifies the name of class that will be modified, bean name has to be resolved before proxy is defined on the type.
Here Proxetta instance as well as advices and pointcuts are created outside the container.