Spring-Anotion-(Spring基于注解配置bean)

一、Spring基于注解的方式配置bean基本介绍和入门案例

1、基本介绍:

基于注解的方式配置bean,主要是项目开发中的组件,比如Action、Service、和Dao.

2、常用的组件注解的形式有:

@Component 表示当前注解标识的是一个组件。

@Controller表示当前注解标识的是一个控制器,通常用于Action类。

@Service表示当前注解标识的是一个处理业务逻辑的类,通常用于Service类。

@Repository表示当前注解标识的是一个持久化层的类,通常用于Dao类。

3、示例:

@Component   //ioc容器扫描到这个注解,就会将Action构造一个bean。

public void Action() {

//....................

}

注意:1>写了注解就不用重复在bean.xml中去写<bean>..<bean/>了。 

           2>注解可以看做是自动配置bean,而不用手工在ioc bean配置文件中去配置,这是另外一种ioc创建bean的体系。 与前文spring手工配置bean 相比,这两种体系都可以独立管理bean,也可以相互补充。

          3>@Component、@Controller、@Service、@Repository这四个注解对于IOC容器来说是同一个意思,ioc容器会扫描到写了某个注解的类,并构建一个bean 。    这四个注解只是为了程序员方便区分 某个类是Action、Service、Dao 中的哪一个。

4、需要引入spring-aop.RELEASE.jar

5、用法案例

1>创建一个类, 并写上注释

import org.springframework.stereotype.Component;

@Component
public class MyComponent {
}

 2、在ioc容器bean.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:p="http://www.springframework.org/schema/p"
       xmlns:util="http://www.springframework.org/schema/util"
       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/util
        http://www.springframework.org/schema/util/spring-util.xsd
       http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">


<!--    打开ioc基于注解的配置-->
<!--    context:component-scan:表示启用ioc基于注解功能-->
<!--    base-package:com.itbull.ioc.component,-->
<!--    表示我们去扫描com.itbul1.ioc.comgonent包的有注解的类.-->

<!--    1.如果我们希望能够扫描 com.itbull.ioc.component 包的所有子包,-->
<!--    则标准的写法是com.itbul1.ioc.component.*-->

    <context:component-scan base-package="com.spring.component"/>


</beans>

 3、在测试方法中,getBean()  。 用MyComponent.class, 当然还可以起别名, 后边会写到

    @Test
    public void test04() {
        MyComponent myComponent = (MyComponent) applicationContext.getBean(MyComponent.class);
        System.out.println(myComponent.getClass());
    }

 4、拿到了bean

6、自动扫描包的小结

细节说明:
1.必须在Spring配置文件中指定“自动扫描的包”,IOC容器才能够检测到当前项目中哪些类被标识了注解,注意到导入context名称空间


<-配置自动扫描的包-><context:component-scan base-package="com.itbull.ioc.component"/>可以使用通配符*方法的指定,比如com.itbull.ioc.*    表示更明确


2.Spring的IOC容器不能检测一个使用了@Controller注解的类到底是不是一个真正的控制器。注解的名称是用于程序员自己识别当前标识的是什么组件。其它的@Service@Repository也是一样的道理[也就是说spring的IOC容器只要检查到注解就会生成对象,但是这个注解的含义spring不会识别,注解是给程序员编程方便看的]


3.resource-pattern="User*.class"表示只扫描满足条件的.

<context:component-scan base-package="com.itbull.ioc.component" resource-pattern="User*.class"/>  // 表示只扫描该包下名称以User打头的类

二、基于注解的方式配置bean-通过id获取

说明:

1.默认情况:标记注解后,类名首字母小写作为id的值。

2.可以使用注解的value属性指定id值,并且value可以省略。 (相当于bean id)

@Controller(value="userAction1")

@Controller("userAction1")

  @Test
    public void test04() {
        MyComponent myComponent = (MyComponent) applicationContext.getBean("myent");
        System.out.println(myComponent.getClass());
    }
import org.springframework.stereotype.Component;

@Component(value = "myent")
public class MyComponent {
}

三、exclude-filter标签

说明 : exclude-filter标签是插在 <context:component->中使用的, 表示生成bean时排除掉某些注解的类

示例:

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

1、在beans.xml中配置排除过滤器,排除@Controler的类不扫描

<!--如何排除不希望扫描的哪些注解类,比如排除com.spring.component下面的@Controller类-->
<!--    1.context:exclude-filter:表示排除哪些类不扫描-->
<!--    2.type="annotation":表示根据注解的方式来排除-->
<!--    3.expression="org.springframework.stereotype.Controller"要排除的注解的全类名-->
    <context:component-scan base-package="com.spring.component">
    <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

2、写注释,一个 写@Controler, 一个写@Repository

package com.spring.component;


import org.springframework.stereotype.Controller;

@Controller(value = "myent")
public class MyComponent {
}

package com.spring.component;

import org.springframework.stereotype.Repository;

@Repository(value = "baseDao")
public class BaseDao {
}
@Test
    public void test04() {
        BaseDao baseDao = (BaseDao) applicationContext.getBean("baseDao");
        System.out.println(baseDao.getClass());

        MyComponent myComponent = (MyComponent) applicationContext.getBean("myent");
        System.out.println(myComponent.getClass());
    }

 4、可以看到@Repository被构建了bean,  而@Controler被排除了

细节:

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

其中type参数有五种类型,常用的两种,assignable表示过滤掉BaseXxx的子类

四、include-filter标签

include标签表示只扫描指定的注解的expression

    <!--annotation-config="false":不再使用默认的扫描机制context:
    include-filter:表示只是扫描指定的注解的类expression
    ="org.springframework.stereotype.Component":注解的全类名-->
    <context:component-scan base-package="com.spring.component" use-default-filters="false">
        <context:include-filter type="annotation"
                                expression="org.springframework.stereotype.Repository"/>
    </context:component-scan>
package com.spring.component;


import org.springframework.stereotype.Controller;

@Controller(value = "myent")
public class MyComponent {
}
package com.spring.component;

import org.springframework.stereotype.Repository;

@Repository(value = "baseDao")
public class BaseDao {
}
    @Test
    public void test04() {
        BaseDao baseDao = (BaseDao) applicationContext.getBean("baseDao");
        System.out.println(baseDao.getClass());

        MyComponent myComponent = (MyComponent) applicationContext.getBean("myent");
        System.out.println(myComponent.getClass());
    }

可以看到 写了注解@Respsitory的BaseDao被扫描到并构建了bean, 而 @Controller没有被扫描到 

五、基于注解的自动装配

1、如果bean之间存在依赖, 那么如何使用注解实现自动装配(即ioc容器如何知道bean之间的关系)?

使用@Autowired 

注意@Autowired的位置

package com.spring.component;

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

@Service
public class MyService {

    private MyDao myDao;

    public MyService() {
    }

    public MyService(MyDao myDao) {
        this.myDao = myDao;
    }

    public MyDao getMyDao() {
        return myDao;
    }

    public void setMyDao(MyDao myDao) {
        this.myDao = myDao;
    }

    public void saveDao() {
        System.out.println("save了一个对象");
    }
}

 

六、spring的bean配置基于泛型依赖 

在有泛型且有依赖的情况下,如何使用注解处理依赖

1、新建以下类

2、

package com.spring.myBean;

public class Book {
}
package com.spring.repository;

public abstract class BaseDao<T> {
    public abstract void save();
}

import com.spring.myBean.Book;
import org.springframework.stereotype.Repository;

@Repository
public class BookDao extends BaseDao<Book>{
    @Override
    public void save() {
        System.out.println("BookDao save");
    }
}
package com.spring.service;

import com.spring.repository.BaseDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;


public class BaseServic<T> {
@Autowired
    private BaseDao<T> baseDao;
    public void save () {
        baseDao.save();
    }

}
package com.spring.service;

import com.spring.myBean.Book;
import org.springframework.stereotype.Service;

@Service
public class BookService extends BaseServic<Book>{

}
@Test
    public void test05() {
        BookService bookService = (BookService) applicationContext.getBean(BookService.class);
        bookService.save();

    }

3、 总共五个类, 从BookService对象直接调用到了BookDao的save方法,其中包含了继承,泛型的关系。

4、代码执行过程简写:

首先BookService调用save方法, 然后jvm 先找到BookService对象,发现它继承了BaseService,又发现BaseService自动装配了BaseDao<T>, 带着泛型参数Book又找到BaseDao,但是发现BaseDao是一个抽象类,于是再去找实现了这个抽象类的BookDao, 最后找到了save()方法,发现需要构造BookDao对象,又发现BookDao已经被构造了, 于是直接调用save()方法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值