Java 杂谈Java Web知识

spring bean的配置方式:xml、@Component、

2019-04-05  本文已影响0人  路过的猪

1 曾经的王者-xml

以我们常说的Service和DAO为例:

// UserDAOImpl.java
public class UserDAOImpl implements UserDAO {
}

// UserServiceImpl.java
public class UserServiceImpl implements UserService {
    private UserDAO userDAO;
}

我们使用xml配置两个bean,以及其需要的依赖:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="userDAO" class="demo.dao.UserDAOImpl" />

    <bean id="userService" class="demo.service.UserServiceImpl">
        <property name="userDAO" ref="userDAO" />
    </bean>
</beans>

2. 横空出世-Java注解(@Component)

这时候的bean我们更喜欢使用@Component@Repository@Service这样的注解进行配置,依赖则使用@Autowired@Resource;然后xml指明一下要扫描的包即可。

// UserDAOImpl.java
package demo.dao;
@Repository
public class UserDAOImpl implements UserDAO {
}

-----------------------

// UserServiceImpl.java
package demo.service;
@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserDAO userDAO;
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd 
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="demo" />

</beans>

注:@Repository@Service等可以看成是继承@Component的注解,在spring容器中,除了被注册成一个bean,除了更加语义化之外(比如@Repository表示操作持久层的bean,@Service表示操作业务逻辑的bean),似乎没有表现出其他特别的用处(或许将来会有额外的表现)。

3. @Configuration 配置类的到来

从Spring3.0,@Configuration用于定义配置类,可替换xml配置文件,被注解的类内部包含有一个或多个被@Bean注解的方法,这些方法将会被ApplicationContext进行扫描,并用于构建bean定义,初始化Spring容器。

3.1 @Bean

仍以UserDAO和UserService为例:

// UserDAOImpl.java
public class UserDAOImpl implements UserDAO {
}

// UserServiceImpl.java
public class UserServiceImpl implements UserService {
    private UserDAO userDAO;
}

我们使用@Configuration进行配置的话:

@Configuration
public class UserBeanConfig {

    @Bean(name = "userDAO")
    public UserDAO userDAO() {
        return new UserDAOImpl();
    }

    @Bean(name = "userService")
    public UserService userService(@Qualifier("userDAO") UserDAO userDAO) {
        UserServiceImpl userService = new UserServiceImpl();
        userService.setUserDAO(userDAO);
        return userService;
    }
}

关于@Configuration,可以理解成与<beans>标签对应;@Bean则是与<bean>标签对应。可以确定的是,xml能干的事情,配置类基本上都能干。

注:这里只是为了展示@Configuration与@Bean的功能,真实项目中业务代码的Bean很少会有人这么玩,@Component与@Autowire仍是最受欢迎的注解。

3.2 @ComponentScan

若UserDAOImpl、UserServiceImpl继续使用注解(@Component@Autowire),扫描的方式,除了xml中的<context:component-scan base-package="demo" />,还可以使用@Configuration +@ComponentScan

package demo.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan("demo")
public class UserBeanConfig {
}

如果不指定扫描的包,则是扫描配置类下对应的包(本例是demo.config)

3.3 SpringBoot中的扫描

大家都知道,一个简单的SpringBoot配置非常简洁:

package demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

关于@SpringBootApplication注解:

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan
public @interface SpringBootApplication {
    ...
}

其中的@SpringBootConfiguration

@Configuration
public @interface SpringBootConfiguration {
}

我们看到,@SpringBootApplication其实非常的简单:
@SpringBootApplication=@Configuration+@ComponentScan+@EnableAutoConfiguration

启动类DemoApplication可以看成是:一个普通的@Configuration配置类+main函数的执行类。main入口进去后,第一个拿到的配置类就是这个,而这是一切的开始。

值得注意的是:@SpringBootApplication中的@ComponentScan其实是没有指定要扫描的包名的,会默认扫描启动类下的包(本例是demo),这也是为什么启动类通常放顶层包下,类似这样的结构:

启动类的位置
上一篇下一篇

猜你喜欢

热点阅读