7.

【Spring】@Configurationアノテーションとは

編集
この記事の要点
  • @ConfigurationJava で Spring 設定を書くためのアノテーション(XML の代替)
  • 内部の @Bean メソッドが Bean を作る工場として機能
  • @Configuration 内の @Bean メソッド呼び出しは シングルトン保証(同じ Bean を返す)
  • @Configuration(proxyBeanMethods = false) でプロキシをオフ(パフォーマンス重視)
  • @ComponentScan / @PropertySource / @Import を組み合わせて構成

 

@Configuration の基本

Spring の Bean 定義は元々 XML(applicationContext.xml)で書いていましたが、Java コードで書く方が型安全・IDE 補完が効くため @Configuration + @Bean が標準になりました。

@Configuration
public class AppConfig {

    @Bean
    public DataSource dataSource() {
        HikariConfig config = new HikariConfig();
        config.setJdbcUrl("jdbc:postgresql://localhost:5432/mydb");
        config.setUsername("user");
        config.setPassword("secret");
        return new HikariDataSource(config);
    }

    @Bean
    public JdbcTemplate jdbcTemplate(DataSource dataSource) {  // 上で定義した Bean を注入
        return new JdbcTemplate(dataSource);
    }

    @Bean
    public RestTemplate restTemplate() {
        RestTemplate rt = new RestTemplate();
        rt.setRequestFactory(new HttpComponentsClientHttpRequestFactory());
        return rt;
    }
}

@Bean メソッドの特性

シングルトン保証(proxyBeanMethods = true)

デフォルトでは @Configuration クラスは CGLib プロキシ化され、@Bean メソッド呼び出しが常に同じインスタンスを返すようになります:

@Configuration
public class AppConfig {

    @Bean
    public FooBean foo() {
        return new FooBean();
    }

    @Bean
    public BarBean bar() {
        return new BarBean(foo());  // ← foo() を呼ぶ
    }

    @Bean
    public BazBean baz() {
        return new BazBean(foo());  // ← もう一度 foo() を呼ぶ
    }
}
// → bar.foo == baz.foo(同じインスタンス、シングルトン保証)

proxyBeanMethods = false(パフォーマンス重視)

@Configuration(proxyBeanMethods = false)
public class LightConfig {

    @Bean
    public FooBean foo() {
        return new FooBean();
    }

    @Bean
    public BarBean bar() {
        return new BarBean(foo());  // ← 直接呼び出し(新インスタンス)
    }
}
// → 引数で受け取る方が安全
@Bean
public BarBean bar(FooBean foo) {  // ← DI で注入
    return new BarBean(foo);
}

@Bean メソッドの属性

@Configuration
public class AppConfig {

    // 名前指定
    @Bean(name = "myDataSource")
    public DataSource dataSource() { ... }

    // 複数名(エイリアス)
    @Bean({"ds", "dataSource"})
    public DataSource dataSource() { ... }

    // 初期化と破棄
    @Bean(initMethod = "init", destroyMethod = "close")
    public ConnectionPool connectionPool() {
        return new ConnectionPool();
    }

    // 自動破棄をオフ
    @Bean(destroyMethod = "")
    public AutoCloseable customResource() { ... }
}

関連アノテーションの組み合わせ

@ComponentScan

@Configuration
@ComponentScan(basePackages = {"com.example.service", "com.example.controller"})
public class AppConfig { ... }

@PropertySource(外部プロパティ読み込み)

@Configuration
@PropertySource("classpath:app.properties")
public class AppConfig {

    @Value("${app.host}")
    private String host;

    @Bean
    public Environment env() { ... }
}

@Import(複数 Configuration を組み合わせ)

@Configuration
@Import({DatabaseConfig.class, SecurityConfig.class, MailConfig.class})
public class AppConfig { ... }

// またはモジュール化
@Configuration
public class DatabaseConfig {
    @Bean public DataSource dataSource() { ... }
    @Bean public JdbcTemplate jdbcTemplate(DataSource ds) { ... }
}

@Configuration
public class SecurityConfig {
    @Bean public PasswordEncoder passwordEncoder() { ... }
}

プロファイル別の Configuration

@Configuration
@Profile("prod")
public class ProdConfig {
    @Bean
    public DataSource dataSource() {
        // 本番用 DB 接続
    }
}

@Configuration
@Profile({"dev", "test"})
public class DevConfig {
    @Bean
    public DataSource dataSource() {
        // 開発用 H2 等
    }
}

# 起動時にプロファイル指定
java -jar app.jar --spring.profiles.active=prod

条件付き Configuration

@Configuration
@ConditionalOnProperty(name = "feature.mail.enabled", havingValue = "true")
public class MailConfig {
    @Bean
    public MailSender mailSender() { ... }
}

@Configuration
@ConditionalOnClass(name = "redis.clients.jedis.Jedis")  // クラスパスに Jedis があれば
public class RedisConfig {
    @Bean
    public RedisTemplate redisTemplate() { ... }
}

@Configuration
@ConditionalOnMissingBean(DataSource.class)  // DataSource Bean がなければ
public class DefaultDataSourceConfig {
    @Bean
    public DataSource dataSource() {
        return new EmbeddedDatabaseBuilder().build();
    }
}

@Configuration と @Component の違い

項目@Configuration@Component
クラス自体Bean 登録Bean 登録
内部の @Beanシングルトン保証呼ぶたびに新インスタンス
CGLib プロキシあり(デフォルト)なし
用途サードパーティ Bean / 設定中心ビジネスロジッククラス

Spring Boot での自動構成

Spring Boot は @SpringBootApplication 内部で @EnableAutoConfiguration を有効にし、starter 依存に応じて自動的に @Configuration クラスを読み込みます:

@SpringBootApplication
// 内部で以下を行う:
// @Configuration
// @EnableAutoConfiguration
// @ComponentScan
public class MyApp {
    public static void main(String[] args) {
        SpringApplication.run(MyApp.class, args);
    }
}

# 起動時に有効な自動構成を見る
java -jar app.jar --debug

# 自動構成を除外
@SpringBootApplication(exclude = {
    DataSourceAutoConfiguration.class,
    SecurityAutoConfiguration.class
})

関連記事

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. @After
  2. @Autowired
  3. @Bean
  4. @Before
  5. @Column
  6. @Component
  7. @Configuration
  8. @Controller
  9. @Data
  10. @Entity
  11. @GeneratedValue
  12. @Id
  13. @Modifying
  14. @PathVariable
  15. @PropertySource
  16. @Repository
  17. @RequestBody
  18. @RequestMapping
  19. @ResponseBody
  20. @RestController
  21. @Service
  22. @SpringBootApplication
  23. @Table
  24. @Transactional
  25. @Value