I am using MapStruct
and to do that I have to define an interface with an according mapping function. It is possible to implement some logic by using a default
method annotated with @BeforeMapping
and @AfterMapping . In such an annotated default method I want to use a configuration class of my SpringBoot application. How can I do this? Can I autowire such a configuration (bean) into an interface? How should such a code look like?
From the documentation and your hint I found out that I can use either a @Context variable or an abstract class instead of using an interface.
I tried both then. Using an abstract class it worked well as demanded but using a @Context variable the default method gets not invoked.
Here's the main mapping method:
@Mapping(target = "myTarget.partNumber", ignore = true)
public MyTarget mapSource2Target(final MySource mySource, final PartNumberMapConfiguration partNumberMapConfiguration);
and the afterMapping method:
@AfterMapping
default void afterMapping(final @MappingTarget MyTarget target, final MySource source, final @Context PartNumberMapConfiguration partNumberMapConfiguration) {. . . }
When I reach the breakpoint where the mapper is invoked, I cannot step into the mapping method. It just steps over...and the code of the afterMapping method is not executed.
Here's the class I intend to use as with @Context:
@Component("PartNumberMap")
@PropertySource("classpath:abc.properties")
@ConfigurationProperties(prefix = "abc")
public class PartNumberMapConfiguration {
private Map<String, String> partNumberMap = new HashMap<String, String>();
public Map<String, String> getPartNumberMap() {
return partNumberMap;
}
public void setPartNumberMap(final Map<String, String> partNumberMap) {
this.partNumberMap = partNumberMap;
}
}
You can't autowire a bean into an interface. However, you can use the @Context
from MapStruct 1.2.0.
For example:
@Mapper
public interface MyMapper {
Target map(Source source, @Context MyCustomService service);
@AfterMapper
void after(Source source, @MappingTarget Target target, @Context MyCustomService service) {
// Do what you need here
}
}
Another option would be to use an abstract class instead of an interface.
@Mapper
public abstract class MyMapper {
private MyCustomService service;
public abstract Target map(Source source);
@AfterMapping
protected after(Source source, @MappingTarget Target target) {
// Use the service here
}
@Autowired
public void setService(MyCustomService service) {
this.service = service.
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.