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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,980评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,178评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,868评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,498评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,492评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,521评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,910评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,569评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,793评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,559评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,639评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,342评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,931评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,904评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,144评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,833评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,350评论 2 342

推荐阅读更多精彩内容