由mybatis-spring总结Spring的一般注解问题,xml的方式,bean的注册和使用

 

  • 一种是@Autowired 、@Resource 、@PostConstruct、@PreDestroy、@PersistenceContext、@Required系列注解

       最原始的使用其他类的方式是 A a=new A();
       这种注解是用来用其他的bean的,代替自动注入(两种方式,一种getBean(),另一种是把自己也配置成bean,property是要使用的那个bean,然后自己的类中就能使用自己的属性了(要使用的那个bean))。
      但是要配合<context:annotation- config/>或者<context:component-scan>(完全可以代替<context:annotation- config/>)使用,因为他们是使上述注解起作用的,也就是说激活已经在application context中注册的bean

  • 另一种是@Component,@Repository,@Service, @Controller @RestController, @ControllerAdvice,  @Configuration系列注解

      这系列注解是声明要将它注解的类注册成bean
      但是要配合<context:component-scan/>标签使用,<context:component-scan>做了<context:annotation-config>要做的事情,还额外支持@Component,@Repository,@Service, @Controller @RestController, @ControllerAdvice, and @Configuration 注解,并且<context:component-scan>扫描base-package并且在application context中注册扫描到的使用注解注入的beans。
这里着重注意第二段话,<context:component-scan>该注解可以扫描并注册你使用注解诸如@controller @service @component..的bean!!!也就是说,你不用xml中显示配置,需要的时候尽管用@Resource或者@Autowired来自动注入!!!
     总结一下就是:component-scan标签默认情况下自动扫描指定路径下的包(含所有子包),将带有 @Component @Repository @Service @Controller标签的类自动注册到spring容器。(@Component等注解是注册bean用的,由<component-scan>将他们扫描并注册。)对标记了 Spring中的 @Required @Autowired @PostConstruct @PreDestroy @Resource @WebServiceRef @EJB   @PersistenceContext @PersistenceUnit等注解的类进行对应的操作使注解生效(包含了annotation-config标签的作用)。(@Autowired等注解是自动注入bean用的,<annotation-config>和<component-scan>是使这些注解起作用的。)


      基于内容,可以知道注册bean、使用bean的方式。

      最原始的使用其他类的方式是 A a=new A()。

      当有了Spring后,我们可以使用IoC注入。

     最基础的注册bean的方式是Spring的配置xml中注册bean,但是有了@Component系列注解加上<context:component-scan/>标签后我们就不用再在Spring的配置xml中一个个注册了

     使用bean的方式,Spring基础的是一种getBean(),另一种是把自己也配置成bean,property是要使用的那个bean,然后自己的类中就能使用自己的属性了(要使用的那个bean);但是有了@Autowired后,只要你注册了bean(@Autowired注解在你使用的时候自动注入的前提是,spring容器中已经有了该bean),你就可以在要使用其他bean的地方(例如Service层)直接使用那个bean。

     @Autowired/@Resource  和  @Component既可以结合使用,单独使用也是可以的。

     但是使用mybatis-spring时,有个问题发生了,那就是不能用@Repository +<context:component-scan/>注册mapper层,必须得用MapperFactoryBean或MapperScannerConfigurer动态代理注册mapper的bean。


      下面结合mybatis-spring的一个简单例子谈注解问题

<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
  <property name="mapperInterface" value="org.mybatis.spring.sample.mapper.UserMapper" />
  <property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>

<bean id="fooService" class="org.mybatis.spring.sample.mapper.FooServiceImpl">
  <property name="userMapper" ref="userMapper" />
</bean>

public interface UserMapper {
  @Select("SELECT * FROM users WHERE id = #{userId}")
  User getUser(@Param("userId") String userId);
} 

public class FooServiceImpl implements FooService {

  private UserMapper userMapper;

  public void setUserMapper(UserMapper userMapper) {
    this.userMapper = userMapper;
  }

  public User doSomeBusinessStuff(String userId) {
    return this.userMapper.getUser(userId);
  }
}

    1.之前只有Mybatis时,用mapper.java和mapper.xml的使用方式是在该用的地方通过getMapper()的方式:BlogMapper mapper = session.getMapper(BlogMapper.class);   Blog blog = mapper.selectBlog(101);

     2.我以为我们可以通过给mapper接口注册bean<bean class="com.  .Mapper.BlogMapper",然后在要使用mapper接口的地方(比如Service层,Main.java)使用。最原始的是spring xml中<bean ...>,然后要使用mapper接口的地方mapper =factory.getBean();mapper.selectBlog(101);或者把Service也配置成一个bean,property是mapper的bean,这样Service就可以使用自己的属性了(这是我想的Spring的IoC注入方式,不过这种方式一般是用于类的,mapper接口应该不能直接这么用)。

    3.事实是mybatis的mapper层是接口,不能直接这么用,应该spring-common.xml中使用代理类MapperFactoryBean配置bean,如上面代码一样。然后在 business/service 对象中以和注入任意 Spring bean 的相同方式直接注入映射器,这样Service里面没法直接也可以使用mapper.java了(这是Spring IoC注入的另一种形式:把自己配成bean直接用属性;)或者在Service层使用@Autowired+<context:component-scan/>;至于能不能getBean("userMapper")我没试过,不知道。

     4.MapperFactoryBean升级版的是使用MapperScannerConfigurer,因为没有必要在 Spring 的 XML 配置文件中注册所有的映射器,相反,你可以使用一个 MapperScannerConfigurer , 它 将 会 查 找 类 路 径 下 的 映 射 器 并 自 动 将 它 们 创 建 成 MapperFactoryBean。在这种情况下,是没法使用Service配置成含属性mapper的bean的方法了,应该Service层通过@Autowired使用mapper。

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
  <property name="basePackage" value="cn.neusoft.mapper" />
</bean>

      5.因为MapperScannerConfigurer也是用来注册bean的,而@Repository +<context:component-scan/>就可以将dao层自动注册成bean,无需在xml中配置,所以我在想,能不能spring-common.xml中不写MapperScannerConfigurer,将Mapper接口用@Repository +<context:component-scan/>注解。经过用项目实验,证明是错误的,会报错没有注册mapper的bean。这让我非常疑惑,@Repository +<context:component-scan/>明明就可以注册dao层的bean,查看一些资料

MyBatis-Spring 提供了一个动态代理的实现:MapperFactoryBean。这个类 可以让你直接注入数据映射器接口到你的 service 层 bean 中。当使用映射器时,你仅仅如调 用你的 DAO 一样调用它们就可以了,但是你不需要编写任何 DAO 实现的代码,因为 MyBatis-Spring 将会为你创建代理。

      所以我猜测是不是因为mybatis的mapper层是接口,是通过代理类实现注册bean的,所以不能通过@Repository +<context:component-scan/>注册,而正常的dao层是可以@Repository +<context:component-scan/>简便注册bean的。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值