Spring支持用注解配置Bean,更简便。

上面的组件,是根据实际情况配的。比如写的一个类,是做业务处理的,那就用注解@Service表示服务层组件,以此类推。将整体分成不同部分。

要在xml加入context命名空间

  1. <!-- 指定Spring IOC容器扫描的包 -->
  2. <context:component-scan base-package="package com.guigu.spring.beans.annotation"></context:component-scan>

这样,就表示要自动扫描 基类包的类以及子包中的类。类中有注解,就会被管理

 例子:

目录结构如下,第一个annotation包为要扫描的包,有下面三个子包:controller、repository、service

类里面都是一个简单的注解和一个方法:

  1. //TestObject.java
  2. package com.guigu.spring.beans.annotation;
  3.  
  4. import org.springframework.stereotype.Component;
  5.  
  6. @Component
  7. public class TestObject {
  8.  
  9. }
  1. //UserController.java
  2. package com.guigu.spring.beans.annotation.controller;
  3. import org.springframework.stereotype.Controller;
  4.  
  5. @Controller
  6. public class UserController {
  7.  
  8. public void execute(){
  9. System.out.println("UserController execute...");
  10. }
  11. }
  1. //UserRepository.java
  2. package com.guigu.spring.beans.annotation.repository;
  3. public interface UserRepository {
  4.  
  5. void save();
  6. }
  7.  
  8. //UserRepositoryImpl.java 继承 UserRepository
  9. package com.guigu.spring.beans.annotation.repository;
  10. import org.springframework.stereotype.Repository;
  11.  
  12. @Repository("userRepository");
  13. public class UserRepositoryImpl implements UserRepository {
  14.  
  15. @Override
  16. public void save() {
  17. System.out.println("UserRepositoryImpl Save...");
  18. }
  19.  
  20. }

写一个继承,为了说明注解命名可以更改,这里改成了userRepository,否则是默认的userRepositoryImpl,下面讲。

  1. //UserService.java
  2. package com.guigu.spring.beans.annotation.service;
  3.  
  4. import org.springframework.stereotype.Service;
  5.  
  6. @Service
  7. public class UserService {
  8.  
  9. public void add(){
  10. System.out.println("UserService add...");
  11. }
  12. }

xml最上面已经配置,最后main函数:

  1. package com.guigu.spring.beans.annotation;
  2.  
  3. import org.springframework.context.ApplicationContext;
  4. import org.springframework.context.support.ClassPathXmlApplicationContext;
  5.  
  6. import com.guigu.spring.beans.annotation.controller.UserController;
  7. import com.guigu.spring.beans.annotation.repository.UserRepository;
  8. import com.guigu.spring.beans.annotation.service.UserService;
  9.  
  10. public class Main {
  11.  
  12. public static void main(String[] args) {
  13.  
  14. ApplicationContext ctx =new ClassPathXmlApplicationContext("beans-annotation.xml");
  15. TestObject to = (TestObject) ctx.getBean("testObject");
  16. System.out.println(to);
  17. UserController userController=(UserController) ctx.getBean("userController");
  18. System.out.println(userController);
  19. UserService userservice=(UserService) ctx.getBean("userservice");
  20. System.out.println(userservice);
  21. UserRepository userRepository=(UserRepository) ctx.getBean("userRepository");
  22. System.out.println(userRepository);
  23. }
  24.  
  25. }

输出如下:说明对象被创建了

xml里面没有bean,那main函数怎么获取Bean呢?

就是用最上面图中蓝色字体。Spring默认命名,名字是它的类名第一个字符小写。如:

UserService.java类中类名是UserService ,获取bean默认名字就是userService

也可以更改,如上面的UserRepositoryImpl类,用了@Repository("userRepository"),表示bean名字为userRepository

在xml中,有一些属性和节点:

resource-pattern:只扫描特定文件

context:include-filter: 子节点表示要包含的组件

context:exclude-filter: 子节点表示要排除在外的组件

  1. <!-- 可以通过resource-pattern指定扫描的资源 -->
  2. <context:component-scan base-package="package com.guigu.spring.beans.annotation"
  3. resource-pattern="repository/*.class">
  4. </context:component-scan>

这样,只会扫描repository包下的类,如果main函数中,还要调用其他类,报错。只能调用repository包下的类。

  1. <!-- context:exclude-filter 子节点指定排除哪些指定表达式的组件 -->
  2. <context:component-scan base-package="package com.guigu.spring.beans.annotation">
  3. <context:exclude-filter type="annotation" expression="package com.guigu.spring.beans.annotation.repository"/> //type类型后面看
  4. </context:component-scan>

这表示不扫描repository子包的文件,若main函数中调用它们,会抛异常

  1. <!-- context:include-filter 子节点指定包含哪些指定表达式的组件, 该子节点需要use-default-filters配合使用 -->
  2. <context:component-scan base-package="package com.guigu.spring.beans.annotation"
  3. use-default-filters="false">
  4. <context:include-filter type="annotation"
  5. expression="package com.guigu.spring.beans.annotation"/>
  6. </context:component-scan>

注意,use-default-filters默认自动扫描全部,要设置成false不自动扫描,才能实现只扫描部分的功能。

<context:include-filter>和<context:exclude-filter>子节点支持多种类型的过滤表达式:

类别 示例 说明
annotation  com.yl.XxxAnnotation 所有标注了XxxAnnotation的类,该类型采用目标类是否标注了某个注解进行过滤
assinable  com.yl.XxxService 所有继承或扩展XxxService的类,该类型采用了目标类是否继承或扩展某个特定类进行过滤
aspectj  com.yl.*Service 所有类名义Service结束的类及继承或扩展它们的类,该类型采用AspectJ表达式进行过滤
regex  com.yl.anno.* 所有com.yl.anno包下的类。该类型采用正则表达式,根据类的类名进行过滤
custom  com.yl.XxxTypeFilter  采用XxxTypeFilter通过代码的方式定义过滤原则。该类必须实现org.springframewor

@Autowired自动装配具有兼容类型的单个bean属性。可以对类成员变量方法构造函数进行标注,完成自动装配的工作。 通过 @Autowired的使用来代替set方法。(property 属性通过调用setter方法进行赋值)

意思就是用它,可以代替xml中的<property name="car" ref="car"> 这样的引用赋值。自动创建bean。

例子:Person类有Car对象,不用 自动装配

  1. //Person类
  2. public class Person {
  3. private Car car;
  4.  
  5. public Car getCar() {
  6. return car;
  7. }
  8. public void setCar(Car car) {
  9. this.car = car;
  10. }
  11. }
  1. //Car类
  2. public class Car {
  3. private String brand;
  4. private double price;
  5.  
  6. public void setBrand(String brand) {
  7. this.brand = brand;
  8. }
  9. public void setPrice(double price) {
  10. this.price = price;
  11. }
  12. }

xml

  1. <bean id="person" class="com.guigu.spring.bean.Person">
  2. <property name="car" ref="car"/>
  3. </bean>
  4. <bean id="car" class="com.guigu.spring.bean.Car">
  5. <property name="brand" value=" aodi"/>
  6. <property name="price" value="200000"/>
  7. </bean>

main

  1. ApplicationContext context = new ClassPathXmlApplicationContext("autowired.xml");
  2. Person person=(Person)ctx.getBean("person");
  3. System.out.println(person);

这是之前的做法。

@Autowired自动装配的方法

查了一下,在之前版本的Spring中,要使用@Autowired,要在xml写上这一行代码才行

  1. 1 <!-- BeanPostProcessor 将自动对标注 @Autowired Bean 进行注入 -->
  2. 2 <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>

但现在spring4,<context:component-scan>自动注册AutowiredAnnotationBeanPostProcessor实例,可以使用@Autowired和@Resource、和@Inject注解(一般用@Autowired)

所以,如果使用了<context:component-scan>,就不用额外注册,不然还是要

  1. //Person类
  2. public class Person {
  3. //@Aotuwired //自动根据xml配置实例car对象
  4. private Car car;
  5.  
  6. }
  1. <bean id="person" class="com.guigu.spring.bean.Person">
  2. //这里就不需要再写ref="car"
  3. </bean>
  4. <bean id="car" class="com.guigu.spring.bean.Car">
  5. <property name="brand" value=" aodi"/>
  6. <property name="price" value="200000"/>
  7. </bean>

结果和不用 @Aotuwired一样,都可以

还可以写在setter上

  1. //Person类
  2. public class Person {
  3. private Car car;
  4. //@Aotuwired
  5. public Car setCar(Car car){
  6. this.car=car;
  7. }
  8. }

回到注解上面的例子:

  1. //UserController.java
  2. package com.guigu.spring.beans.annotation.controller;
  3. import org.springframework.stereotype.Controller;
  4.  
  5. @Controller
  6. public class UserController {
  7.  
  8. public void execute(){
  9. System.out.println("UserController execute...");
  10. }
  11. }
  1. // main函数
  2. public class Main {
  3.  
  4. public static void main(String[] args) {
  5. private UserController userController;
  6. ApplicationContext ctx =new ClassPathXmlApplicationContext("beans-annotation.xml");
  7. userController.execute(); // 报错
  1. }
    9 }

在main函数声明userController然后直接调用它的方法,这样显然不行,因为userController都还没有创建,这时用@Autowired就很简单

  1. // main函数
  2. public class Main {
  3.  
  4. public static void main(String[] args) {
  5. //@Autowired
  6. private UserController userController;
  7. ApplicationContext ctx =new ClassPathXmlApplicationContext("beans-annotation.xml");
  8. userController.execute();//不报错
  9. }
  10. }

这样,就自动配置创建了userController对象,可以直接使用

注意①:@Autowired要想成功配置,得先扫描得到,就是UserController类一定要能被扫描到。

注意②:@Autowired遇到相同两个类

  1. //UserRepository
  2. package com.guigu.spring.beans.annotation.repository;
  3. public interface UserRepository {
  4.  
  5. void save();
  6. }
  7.  
  8. //UserRepositoryImpl 继承 UserRepository
  9. package com.guigu.spring.beans.annotation.repository;
  10. import org.springframework.stereotype.Repository;
  11.  
  12. @Repository("userRepository"); //这里
  13. public class UserRepositoryImpl implements UserRepository {
  14.  
  15. @Override
  16. public void save() {
  17. System.out.println("UserRepositoryImpl Save...");
  18. }
  19. //UserRepositoryImpl2 继承 UserRepository
  20. @Repository
  21. public class UserRepositoryImpl2 implements UserRepository {
  22.  
  23. @Override
  24. public void save() {
  25. System.out.println("UserRepositoryImpl2 Save...");
  26. }
  27. }
  1. // main函数
  2. public class Main {
  3.  
  4. public static void main(String[] args) {
  5. //@Autowired
  6. private UserRepository userRepository ;
  7. ApplicationContext ctx =new ClassPathXmlApplicationContext("beans-annotation.xml");
  8. userRepository .save();
  9. }
  10. }

main函数中有@Autowired,自动创建对象,但UserRepository 类却有两个接口,它要去创建哪一个呢?

:默认情况下,若有两个,去找名字相同的,就是还没实例的这个userRepository ,若找到和它名字一样的,上面 @Repository("userRepository"); 写了名字,那就找它了。

若不是这样写@Repository("userRepository");而是 @Repository(),那就报错了。

注意③:解决②的另一个方法

若@Repository("userRepository");改成@Repository(),main函数会报错。

改一下main函数

  1. // main函数
  2. public class Main {
  3.  
  4. public static void main(String[] args) {
  5. //@Autowired
  6. //Qualifier("userRepositoryImpl ")
  7. private UserRepository userRepository ;
  8. ApplicationContext ctx =new ClassPathXmlApplicationContext("beans-annotation.xml");
  9. userRepository .save();
  10. }
  11. }

用Qualifier("userRepositoryImpl ");表示去找userRepositoryImpl 实例,这样也解决了。

Spring学习记录(十一)---使用注解和自动装配的更多相关文章

  1. 使用Spring的JavaConfig 和 @Autowired注解与自动装配

    1 JavaConfig  配置方法 之前我们都是在xml文件中定义bean的,比如: 1 2 3 4 5 6 7 8 <beans xmlns="http://www.springf ...

  2. Spring学习七----------Bean的配置之自动装配

    © 版权声明:本文为博主原创文章,转载请注明出处 Bean的自动装配(Autowiring) no:不启用自动装配,此时需要手动注入.参考:Spring学习三----------注入方式 defaul ...

  3. 我的Spring学习记录(四)

    虽然Spring管理这我们的Bean很方便,但是,我们需要使用xml配置大量的Bean信息,告诉Spring我们要干嘛,这还是挺烦的,毕竟当我们的Bean随之增多的话,xml的各种配置会让人很头疼. ...

  4. 我的Spring学习记录(五)

    在我的Spring学习记录(四)中使用了注解的方式对前面三篇做了总结.而这次,使用了用户登录及注册来对于本人前面四篇做一个应用案例,希望通过这个来对于我们的Spring的使用有一定的了解. 1. 程序 ...

  5. 我的Spring学习记录(二)

    本篇就简单的说一下Bean的装配和AOP 本篇的项目是在上一篇我的Spring学习记录(一) 中项目的基础上进行开发的 1. 使用setter方法和构造方法装配Bean 1.1 前期准备 使用sett ...

  6. Spring 学习记录3 ConversionService

    ConversionService与Environment的关系 通过之前的学习(Spring 学习记录2 Environment),我已经Environment主要是负责解析properties和p ...

  7. Spring 学习记录8 初识XmlWebApplicationContext(2)

    主题 接上文Spring 学习记录7 初识XmlWebApplicationContext refresh方法 refresh方法是定义在父类AbstractApplicationContext中的. ...

  8. Spring 学习记录6 BeanFactory(2)

    主题 除了Spring 学习记录5 BeanFactory 里写的几个接口外,BeanFactory的实现类还实现了一些其他接口,这篇文章主要介绍这些接口和实现类. 结构 DefaultListabl ...

  9. Spring学习七:ComponentScan注解

    今天主要从以下几个方面来介绍一下@ComponentScan注解: @ComponentScan注解是什么 @ComponentScan注解的详细使用 1.ComponentScan注解是什么 其实很 ...

随机推荐

  1. Maven 配置远程仓库

    最近要用到一个包:spark-1.6.0-cdh5.8.2,在https://mvnrepository.com网站上搜到该包的pom.xml语句.但是看到下面有这样一句话: 该包在图中所述repos ...

  2. div高度根据内容自动增大

    1.很多时候我们希望容器高度能够自适应内部元素的变化,需要用到min-height属性. 2.有时候用了min-height还是不会随着内容自适应高度,您需要检查下容器的子元素是不是有浮动属性,当子元 ...

  3. CentOS6.5的vsftp搭建流程(一)

    前几次搭建FTP都失败了,不是登陆不了,就是目录没有权限.现在终于摸索出了靠谱的操作流程,分享之~ 1. 查看是否安装了vsftpd,未安装则安装 [root@iZ283tian2dZ /]# rpm ...

  4. [BZOJ1562][ZJOI2007] 最大半连通子图

    Description Input 第一行包含两个整数N,M,X.N,M分别表示图G的点数与边数,X的意义如上文所述.接下来M行,每行两个正整数a, b,表示一条有向边(a, b).图中的每个点将编号 ...

  5. bzoj1503郁闷的出(cheng)纳(xu)员

    好痛苦,,,WA了不知道多少遍 错的服了,,, 如果某员工的初始工资低于工资下界,他将立刻离开公司 我也不知道是我语文有问题还是题目有毒,反正这个东西好像不应该算在离开公司的总人数的答案里... 让我 ...

  6. 压缩png质量不改变像素

    private static byte[] CompressionImage(Bitmap bitmap, Stream fileStream, long quality) { using (Syst ...

  7. Cannot run gnome extension in browser

    Error Message: We cannot detect a running copy of GNOME on this system, so some parts of the interfa ...

  8. POJ 1163 The Triangle(简单动态规划)

    http://poj.org/problem?id=1163 The Triangle Time Limit: 1000MS   Memory Limit: 10000K Total Submissi ...

  9. 关于兼容IE的一些策略

    --css 盒子模型下的 box-sizing 属性,只兼容到ie8: -moz-box-sizing: border-box; -webkit-box-sizing: border-box; -o- ...

  10. win10调用局域网内xp系统上的打印机

    首先在xp系统上配置允许远程连接,然后设置账户密码,最后配置打印机,允许共享. 打开自己win10 ,win+R ,输入\\目标电脑ip\打印机名,确定,输入账户,密码. win+X - P-进入控制 ...