Spring——bean的装配

创建应用对象之间协作关系的行为通常称为装配(wiring),这也是依赖注入(DI)的本质。

Spring提供了三种装配bean的方式

  1. 在XML中进行显示配置;
  2. 在Java中进行显示配置;
  3. 隐式的bean发现机制和自动装配

自动装配bean

自动装配优势:

便利,自动化装配,隐式配置代码量少。

自动装配限制:

基本数据类型的值、字符串字面量、类字面量无法使用自动装配来注入。
装配依赖中若是出现匹配到多个bean(出现歧义性),装配将会失败。

Spring实现自动装配两个步骤:

组件扫描(component scanning):Spring会扫描@Component注解的类,并会在应用上下文中为这个类创建一个bean。
自动装配(autowiring):Spring自动满足bean之间的依赖。

使用到的注解:

@Component:表明这个类作为组件类,并告知Spring要为这个类创建bean。默认bean的id为第一个字母为小写类名,可以用value指定bean的id (@Component("userDao"))。
@Configuration:代表这个类是配置类。
@ComponentScan:启动组件扫描,默认会扫描所在包以及包下所有子包中带有@Component注解的类,并会在Spring容器中为其创建一个bean。可以用basePackages属性指定包。
@ComponentScan("com.test")
@ComponentScan(basePackages={"com.test","com.sys"})
@ComponentScan(basePackageClasses={UserDaoImpl.class,UserServiceImpl.class})
@RunWith(SpringJUnit4ClassRunner.class):以便在测试开始时,自动创建Spring应用上下文。
@ContextConfiguration:告诉在哪加载配置。
@Autowired:将一个类的依赖bean装配进来。

首先创建两个接口以及他们的实现类,实现类需要用@Component进行注解:

public interface UserDao {
    public void save(String name);
}

@Component
public class UserDaoImpl implements UserDao {

    @Override
    public void save(String name) {
        // TODO Auto-generated method stub
        System.out.println("保存了数据:" + name);
    }

}
public interface UserService {
    public void getName(String name);
}

@Component
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDao userDao;
    
    @Override
    public void getName(String name) {
        userDao.save(name);
    }

}

spring默认是不启用组件扫描的,实现组件自动扫描方式有两种:

  1. 可以在XML中配置加上<context:component-scan base-package="xx"/>。
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"

xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-4.0.xsd">
    
    
    
    <!-- 扫描路径 -->
    <context:component-scan base-package="com.test">    </context:component-scan>


</beans>

测试类:

//SpringJUnit4ClassRunner测试用,测试开始的时候自动创建Spring的应用上下文。
@RunWith(SpringJUnit4ClassRunner.class)
//测试用,去指定类加载配置
@ContextConfiguration(locations="spring.xml")
public class UserTest {
    @Autowired
    private UserService userService;
    
    @Test
    public void test() {
        userService.getName("zhangsan");
    }
}
  1. 在新建一个配置类,类中可以什么不用写,在配置类上加上@ComponentScan注解,spring会自动扫描改配置类所在的包,一般应该倾向xml配置。
    配置类:
@Configuration
@ComponentScan
public class UserConfig {

}

测试类:

//SpringJUnit4ClassRunner测试用,测试开始的时候自动创建Spring的应用上下文。
@RunWith(SpringJUnit4ClassRunner.class)
//测试用,去指定类加载配置
@ContextConfiguration(classes = UserConfig.class)
public class UserTest {
    @Autowired
    private UserService userService;
    
    @Test
    public void test() {
        userService.getName("zhangsan");
    }
}

通过Java代码装配bean

优点:

可以实现基本数据类型的值、字符串字面量、类字面量等注入。

使用到的注解:

@Bean:默认情况下配置后bean的id和注解的方法名一样,可以通过name属性自定义id。
@ImportResourse:将指定的XML配置加载进来
@Import:将指定的Java配置加载进来。
注:不会用到@Component与@Autowired注解。
首先创建两个接口以及他们的实现类,不需要用@Component进行注解:

public interface UserDao {
    public void save(String name);
}

public class UserDaoImpl implements UserDao {

    @Override
    public void save(String name) {
        // TODO Auto-generated method stub
        System.out.println("保存了数据:" + name);
    }

}
public interface UserService {
    public void getName(String name);
}

public class UserServiceImpl implements UserService {

    private UserDao userDao;
    
    public UserServiceImpl(UserDao userDao) {
        this.userDao = userDao;
    }
    
    @Override
    public void getName(String name) {
        userDao.save(name);
    }

}

配置类:

public class UserConfig {

    @Bean
    public UserService userService(UserDao userDao){
        return new UserServiceImpl(userDao);
    }
    
    @Bean
    public UserDao userDao(){
        return new UserDaoImpl();
    }
}

测试类:

@RunWith(SpringJUnit4ClassRunner.class)
//测试用,去指定类加载配置
@ContextConfiguration(classes = UserConfig.class)
public class UserTest {
    @Autowired
    private UserService userService;
    
    @Test
    public void test() {
        userService.getName("zhangsan");
    }
}

通过XML装配bean

优点:什么都能做。
缺点:配置繁琐。
使用到的标签:
<bean>:将类装配为bean,也可以导入java配置。属性id是为bean指定id,class是导入的类。
<constructor-arg>:构造器中声明DI,属性value是注入值,ref是注入对象引用。
spring的c-命名空间:起着和<constructor-arg>相似的作用。
<property>:设置属性,name是方法中参数名字,ref是注入的对象。
Spring的p-命名空间:起着和<property>相似的作用。
<import>:导入其他的XML配置。属性resource是导入XML配置的名称。

1、设值注入:即通过XML中配置bean的依赖类,通过层级property属性,来配置依赖关系,然后Spring通过setter方法,来实现依赖类的注入;
<property name="xxx" ref="xxx"></property>
2、构造器注入:方法同设值注入,不过具体实现的方法是通过显示的创造一个构造方法,构造方法的参数名称要与XML中配置的name名称一致,XML配置的标签为constructor-arg
<constructor-arg name="xxx" ref="xxx"></constructor-arg>
配置文件:

<?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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"

xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-4.0.xsd">
    
    
    
    <!-- 扫描路径 -->
<!--    <context:component-scan base-package="com.test">    </context:component-scan> -->
<bean id="userDao" class="com.test.UserDaoImpl"></bean>
<bean id="userService" class="com.test.UserServiceImpl">
<constructor-arg ref="userDao"/>
</bean>

</beans>

测试类:

public class MainTest {
    public static void main(String[] args) {
        ApplicationContext  context = new ClassPathXmlApplicationContext("file:D:\\spring-dao.xml");
        UserService userService = context.getBean(UserService.class);
        userService.getName("zhangsan");
    }
}

#混合使用三种装配:

1.在类上可以使用@ import(bbsConfig.class)组合其他java注解

2.在类上使用@ imortResource("classpath:spring-dao.xml")组合其他xml注解

3.在类上可以使用@ContenxtConfiguration包含class或者xml

4.在xml中可以用<import resource="spring-dao.xml">引入xml注解,也可以使用<bean class="com.bbs.dao.Userdao">引入java注解

参考文献:
https://www.cnblogs.com/maxshare/p/10467761.html
https://www.cnblogs.com/JimKing/p/8811119.html
https://blog.csdn.net/feng_zhiyu/article/details/81142850

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容