I am new to spring framework..
Here is my question: How i can wrap beans in runtime onto another class?
I have classes as follows for every data struct && java type:
@Component
public class ByteCodec extends Codec<Byte> {
public ByteCodec() {
super(Byte.class);
}
public void encode(... buffer, Byte object) {
buffer.writeByte(object);
}
public Byte decode(... buffer) {
return buffer.readByte();
}
}
and this class is a managed spring singleton. I need to wrap that codec by next class:
class OptionalCodec<T> extends Codec<Boolean> {
public OptionalCodec(Codec<T> clazz) {
}
... some implementation of encode && decode method's ...
}
How i can do this? Hint: i want automatic wrap in RUNTIME for every Codec instance..
And how to extend Autowired annotation, like that:
@AutowireCodec(targetClass=Integer.class, canBeNull=false)
private Codec<Integer> codec;
And how to do registry of the all runtime-created codecs with map:
Map<*MyCodecInfoClass*, Codec>
?? Thanks for any replies!
Spring @Bean Annotation is applied on a method to specify that it returns a bean to be managed by Spring context. Spring Bean annotation is usually declared in Configuration classes methods. In this case, bean methods may reference other @Bean methods in the same class by calling them directly.
Annotating a class with the @Configuration indicates that the class can be used by the Spring IoC container as a source of bean definitions. The @Bean annotation tells Spring that a method annotated with @Bean will return an object that should be registered as a bean in the Spring application context.
There are several ways to configure beans in a Spring container. Firstly, we can declare them using XML configuration. We can also declare beans using the @Bean annotation in a configuration class. Finally, we can mark the class with one of the annotations from the org.
Spring allows you to inject beans by types and generic types out of the box, so for your use case I don't think it is really necessary to create a new Autowired annotation. You can simply use the existing @Autowired like this:
@Autowired
private Codec<Byte> codec;
Just keep in mind that if you define more than one bean for the same generic type and you use the code above, you'll get an error because more than one bean exist with that definition. You could get around that injecting a collection instead of a single object, for example:
@Autowired
private List<Codec<Byte>> byteCodecs;
Or if you want all codecs, regardless its generic type you can simply do something like this:
@Autowired
private List<Codec<?>> allCodecs;
Regarding your question on instance wrapping, I'm not sure if I fully understand what you're trying to achieve but you can inject a codec into another codec like I stated above, or you can take a look to Spring AOP and use it to wrap calls to your beans: http://docs.spring.io/spring/docs/current/spring-framework-reference/html/aop.html
I'm still not sure what would be the purpose of of the OptionalCodec
as it will accept booleans on the encode/decode methods. The OptionalCodec
is a different class than the base Codec
interface, so if you do:
@Autowired
private OptionalCodec<Byte> codec;
Will inject the optional Byte codec. If you do:
@Autowired
private Codec<Byte> codec;
Will inject the original Byte codec. But if you do:
@Autowired
private Codec<Boolean> codec;
It will match all the OptionalCodec
beans (because the type signature for an OptionalCodec
is Codec<Boolean>
) and throw an error as it will not be able to pick a single one.
That said, if you really need to fine tune the autowiring of same type of beans I suggest you to check this relevant section of Spring documentation where annotations like @Primary
and @Qualifier
are explained, and let you do exactly that: http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html#beans-autowired-annotation-qualifiers
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With