SpringFramework学习-(9)基于注解配置bean

前面几篇文章介绍了基于配置文件的bean的配置,Spring还提供基于注解形式来配置bean。
Spring提供了组件扫描(component scanning),能够从classpath下自动扫描侦测和具有特定注解的组件。
特定组件包括:

@Controller
@Service
@Repository
@Component

对于扫描到的组件,Spring有默认的命名策略:使用非限定类名,第一个字母小写,也可以在注解中通过value属性值标识组件的名称。
什么意思呢,不如先看一个例子:
1.创建接口UserDao
定义两个方法

package com.jd.annotation.dao;

public interface UserDao {

    public void add(int a, int b);

}

2.创建UserDao的实现UserDaoImpl
实现接口方法,打印传递的数据之和和之差。
在UserDaoImpl上面标记为@Repository,通过value属性值设置为userDao

package com.jd.annotation.dao;

import org.springframework.stereotype.Repository;

@Repository("userDao")
public class UserDaoImpl implements UserDao{

    public void add(int a, int b) {
        int result = a+b;
        System.out.println("调用加法操作,result:"+result);

    }
}

3.创建userService接口

package com.jd.annotation.service;

public interface UserService {

    public void addInt(int a,int b);
}

4.创建UserService接口的实现类UserServiceImpl
service层使用@Service标记,并设置value值为userService,在该类中引用UserDao接口,名字命名为userDao与UserDaoImpl的注解中设置的值对应。
@Autowired为提供的自动注入的注解,如果单纯的引用useDao为null,使用该注解后会为userDao实例化。也可以使用@Resource进行配置(@Resource是javax包下提供的注解方式,@Autowired是Spring提供的注解方式)。

像这种通过@Autowired方式注入,如果在IOC容器中找不到该实例,那么Spring启动时就会报错。比如这里的UserDaoImpl并没有通过注解或者配置文件加入到SpringIoC容器,那么在启动的时候就会报错。这个时候怎么解决呢?
可以在@Autowired中配置是否需要:@Autowired(required=false)忽略该bean的存在。

那么问题又来了,如果我的一个接口有多个实现类怎么办呢,我的@Autowired该装配那个实现类呢?

1.通过上面介绍的在注解的后面添加value值指定到底是那个bean,如@Repository(“userDao”),那么就会按照userDao寻找
2.通过在引用上面添加
@Qualifier("userDao")
private UserDao userDao;
package com.jd.annotation.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.jd.annotation.dao.UserDao;

@Service("userService")
public class UserServiceImpl implements UserService{

    @Autowired
    //@Autowired(required=false)
    private UserDao userDao;

    public void addInt(int a ,int b) {
        userDao.add(a, b);
    }
}

5.配置包扫描
创建配置文件springannotation.xml
上面提到spring就是通过一个扫描组件,对指定的注解扫描加载注册的。

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

    <!-- 
        base-package:扫描 com.jd.annotation包及其下面的子包,
        resource-pattern:指定只扫描哪个子包。如:dao/*.class
     -->
    <context:component-scan base-package="com.jd.annotation"/>

</beans>

与之前的配置文件方式不同,这里只使用了以行的配置,配置包扫描。

6.测试:

package com.jd.annotation;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.jd.annotation.service.UserService;

public class AnnotationTest {

    private ApplicationContext ac = null;
    private UserService userService = null;

    {
        ac = new ClassPathXmlApplicationContext("springannotation.xml");
        userService = ac.getBean(UserService.class);
    }

    @Test
    public void testAnnotation(){
        userService.addInt(1, 2);
    }
}

结果:

调用加法操作,result:3

虽然我们并没有在配置文件中将所有的bean都进行配置,但是很显然在我们调用该bean的时候,该bean已经被加载到spring的IOC容器之中。

这其中有一些细节问题:
比如扫描的配置:

<context:component-scan base-package="com.jd.annotation">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
    </context:component-scan>

或者是

<!--如果需要扫描指定的某个包,需要修改use-default-filters=false,不然会扫描所有base-package包下的内容-->
<context:component-scan base-package="com.jd.annotation" use-default-filters="false">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
    </context:component-scan>

提供了<context:include-filter ><context:exclude-filter>

<context:include-filter > 指定需要扫描的注解
<context:exclude-filter> 指定不需要扫描的注解
比如在配置springmvc的时候,由于springmvc只负责前后台的交互,所以在配置springmvc配置文件的时候就可以指定只扫描@Controller注解,而在spring的applicationContext配置文件中可以忽略前端的@Controller注解。

也可以通过type=”assignable”配置只扫描某个类或者不扫描某个类。

<context:component-scan base-package="com.jd.annotation">
        <context:exclude-filter type="assignable" expression="com.jd.annotation.dao.UserDaoImpl"/>
    </context:component-scan>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值