0

Follow up to this question

I also tried this, but it blows up with not having a noargs constructor (you can do this with services/controllers/components now, so why doesn't it work here?)

@Configuration
class MyConfig {

    @Autowired
    MyConfig( final ObjectMapper mapper ) {
       ...
    }
}

and yet this works

@Configuration // or @Service or some bean
class SomeClass ... {

    @Autowired
    private ObjectMapper objectMapper;

    @PostConstruct
    private void configureObjectMapper() {
        objectMapper.disable( SerializationFeature.WRITE_DATES_AS_TIMESTAMPS );
    }

}

why isn't @Configuration working like other spring managed classes?

Community
  • 1
  • 1
xenoterracide
  • 16,274
  • 24
  • 118
  • 243
  • Please show us how you use the configuration. An mcve. – Sotirios Delimanolis Oct 03 '15 at 18:05
  • @SotiriosDelimanolis a what? linked question contained more information... but they're `@Configuration` they're autoloaded, no direct usage. Spring Rest and Spring MVC use `ObjectMapper`. – xenoterracide Oct 03 '15 at 18:08
  • OP, note that you did misspell the annotation name. – chrylis -cautiouslyoptimistic- Oct 03 '15 at 18:12
  • @SotiriosDelimanolis The question is entirely answerable as posed. This is a weird but known quirk with Spring configuration classes with a direct answer. – chrylis -cautiouslyoptimistic- Oct 03 '15 at 18:13
  • @chrylis oh that's a typo in the question, I'll fix that, all of this stuff did compile locally. – xenoterracide Oct 03 '15 at 18:14
  • @chrylis There's no reason the `@Autowired` field would work, but the method wouldn't. Their example should work fine, unless they have something they aren't showing that's messing with the `@Configuration`. – Sotirios Delimanolis Oct 05 '15 at 16:13
  • @SotiriosDelimanolis and yet as demonstrated in the updated question, adding `@Requried` to the method does work... and no I'm messing with `@Configuration` in anyway. – xenoterracide Oct 05 '15 at 23:58
  • That's why I'm asking for a complete example, because I don't believe you. – Sotirios Delimanolis Oct 06 '15 at 00:05
  • @SotiriosDelimanolis follow the link to the previous question, it provides a full pom, or I suppose if you want [a complete example](https://bitbucket.org/xenoterracide/modern-spring-web-development/src/7db512c789412c02394d561d6087dfb1008a3a33/src/main/java/com/xenoterracide/example/config/Jackson.java?at=master&fileviewer=file-view-default) remove `@Required` from it – xenoterracide Oct 06 '15 at 00:05
  • What I mean by _complete example_ is something you can run. What do you do with the `Jackson` class? This seems like a Spring Boo application. Let me give it a shot. – Sotirios Delimanolis Oct 06 '15 at 00:16
  • I cloned your repo and it works fine without the `@Required`, the method is invoked. – Sotirios Delimanolis Oct 06 '15 at 00:27
  • @SotiriosDelimanolis I will reinvestigate after work, perhaps something was going on that is not so easy to observe... Like I've been testing out the new devtools... perhaps it was not updating the class, or perhaps I have a stale class and didn't realize it. – xenoterracide Oct 06 '15 at 00:36
  • Disable Spring's logging and just add a dumb `System.out.println` statement. Don't even debug. – Sotirios Delimanolis Oct 06 '15 at 00:40
  • @SotiriosDelimanolis *if* you are correct, that wouldn't fix the problem (in and of itself), the problem would be a stale class. And the fix would be evident by not getting a floating point for a timestamp. – xenoterracide Oct 06 '15 at 02:55
  • I'm here to help fix the problem. I'm trying to eliminate possibilities. Your question, as it stands, is not reproducible. If you figure it out, great. Otherwise, you can edit it and we can go from there. – Sotirios Delimanolis Oct 06 '15 at 02:58
  • @SotiriosDelimanolis yeah looks like it was a stale class or stale load, likely a problem with the new dev-tools. I'm unsure, all I know is that I had tried it, it didn't work, added `@Required` it started working, now it just works. My original question is still basically valid, I'll just remove the setter injection parts. – xenoterracide Oct 06 '15 at 04:06
  • Note that [this](http://stackoverflow.com/questions/10650196/how-to-configure-mappingjacksonhttpmessageconverter-while-using-spring-annotatio) is a more appropriate way to configure your `MappingJackson2HttpMessageConverter`'s `ObjectMapper` instance in a Spring MVC application. – Sotirios Delimanolis Oct 06 '15 at 04:31

1 Answers1

4

I don't recognize your first example at all and have no idea where it would work.

The second example, constructor injection, doesn't work specifically on configuration classes because Spring does a significant amount of magic to analyze and solve the dependency graph before it starts building beans. Configuration classes are actually proxied so that their @Bean methods can make self calls and still get the singleton instances (or whatever the appropriate scope is). Because a configuration class can provide beans that it itself depends on, Spring requires a no-arg constructor so that it can build the instance a piece at a time.

My preferred alternative is to use parameter injection on my @Bean methods, which requires no special annotation.

chrylis -cautiouslyoptimistic-
  • 75,269
  • 21
  • 115
  • 152
  • the first is a form of `setter` injection, though I wasn't setting anything. normally when constructing a bean, spring will call setters annotated with @Autowired, it's more scalable than constructor injection but doesn't break encapsulation like field injection does. Though it's possible there is more to setter inject than what I'm doing. – xenoterracide Oct 03 '15 at 18:16
  • The only problem with `@Bean` (although) maybe I don't understand something about that too, is I'm just configuring an existing Bean here, not returning one. Though maybe `@Bean` doesn't need to return anything...? – xenoterracide Oct 03 '15 at 18:23
  • @xenoterracide That's not a setter, though. What you may be thinking of is some of the configurer classes, which implement interfaces for post-processing beans. Those don't have specialized annotations because they implement specific methods. – chrylis -cautiouslyoptimistic- Oct 03 '15 at 18:40
  • http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#beans-autowired-annotation says "You can also apply the annotation to methods with arbitrary names and/or multiple arguments:" – xenoterracide Oct 03 '15 at 18:49
  • @xenoterracide Strange; I've never actually ever seen that used. – chrylis -cautiouslyoptimistic- Oct 03 '15 at 18:54
  • I've just updated my question with an example of it working, it appears that making it `@Required` forces it to get called... – xenoterracide Oct 03 '15 at 18:59
  • `@Configuration` is a special annotation that stands apart from other Spring annotations like `@Component`: http://stackoverflow.com/questions/12229282/difference-between-spring-annotations. The [JavaDoc of the annotation](http://docs.spring.io/autorepo/docs/spring/4.1.1.RELEASE/javadoc-api/org/springframework/context/annotation/Configuration.html) is also quite informative. – hotzst Oct 03 '15 at 19:58