大数据平台 单例模式 做推广 ant arm 后台管理网页模板 angularjs教程 jq选择第一个子元素 idea生成main方法 虚拟机重启命令 java清空数组 mysql增删改查语句 mysql卸载重装 python编程练习题 java 大文件上传 svn安装后右键不显示 python正则提取字符串 java实现接口 java获取年份 java求和 java8时间 学java基础 java系统时间 java包名 java获取文件 java语言运算符 枪神传说辅助 御旌是什么 groupy extjs视频教程 魔兽地图七个人 php四舍五入 ps色阶快捷键 联发科mt6750 phpword 1667 ps反向选择的快捷键 平面设计软件下载 设备管理器在哪 dnf传说
当前位置: 首页 > 学习教程  > 编程语言

2.bean的作用域、bean自动装配、注解实现自动配置、注解开发、javaconfig实现注解

2021/2/13 20:08:03 文章标签: 测试文章如有侵权请发送至邮箱809451989@qq.com投诉后文章立即删除

文章目录 1.bean的作用域 2.bean自动装配 2.1测试 2.2ByName自动装配 2.3ByType自动装配 3.注解实现自动配置 4.注解开发 5.javaconfig实现注解 1.bean的作用域 1.单例模式…

文章目录
         1.bean的作用域
         2.bean自动装配
                 2.1测试
                 2.2ByName自动装配
                 2.3ByType自动装配
         3.注解实现自动配置
         4.注解开发
         5.javaconfig实现注解

1.bean的作用域

在这里插入图片描述
1.单例模式(Spring默认机制)

<bean id="user2" class="com.kuang.pojo.User" c:name="狂神" c:age="22" scope="singleton"/>

2.原型模式:每次从容器中get的时候,都会产生一个新对象

<bean id="user2" class="com.kuang.pojo.User" c:name="狂神" c:age="22" scope="prototype"/>

3.其余的request、session、application、这些只能在web开发中使用到
2.bean自动装配

  • 自动装配是Spring满足bean依赖一种方式
  • Spring会在上下文中自动寻找,并自动给bean装配属性

在Spring中有三种装配的方式:

  • 在xml中显式的配置;
  • 在java中显式配置;
  • 隐式的自动装配bean【重要】

2.1测试
1.新建一个项目
2.新建两个实体类,Cat Dog 都有一个叫的方法

public class Cat {
   public void shout() {
       System.out.println("miao~");
  }
}
public class Dog {
   public void shout() {
       System.out.println("wang~");
  }
}

3.新建一个用户类 User

public class User {
   private Cat cat;
   private Dog dog;
   private String str;
}

4.编写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"
      xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">

   <bean id="dog" class="com.redeemi.pojo.Dog"/>
   <bean id="cat" class="com.redeemi.pojo.Cat"/>

   <bean id="user" class="com.redeemi.pojo.User">
       <property name="cat" ref="cat"/>
       <property name="dog" ref="dog"/>
       <property name="str" value="张三"/>
   </bean>
</beans>

5、测试

public class MyTest {
   @Test
   public void testMethodAutowire() {
       ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
       User user = (User) context.getBean("user");
       user.getCat().shout();
       user.getDog().shout();
  }
}

2.2 ByName自动装配
autowire byName (按名称自动装配)
由于在手动配置xml过程中,常常发生字母缺漏和大小写等错误,而无法对其进行检查,使得开发效率降低
采用自动装配将避免这些错误,并且使配置简单化。

测试:
1.修改bean配置,增加一个属性 autowire=“byName”

<bean id="user" class="com.redeemi.pojo.User" autowire="byName">
   <property name="str" value="张三"/>
</bean>

2.再次测试,结果正确
3.将 cat 的bean id修改为 catXXX
4.再次测试, 执行时报空指针java.lang.NullPointerException。因为按byName规则找不对应set方法,真正的setCat就没执行,对象就没有初始化,所以调用时就会报空指针错误。

<!--
    byName:会自动在容器上下文中查找,和自己对象set方法后面的值对应的bean id!
        -->
    <bean id="people" class="com.redeemi.pojo.People" autowire="byName">
        <property name="name" value="张三"/>
    </bean>

2.3 ByType自动装配
autowire byType (按类型自动装配)
使用autowire byType首先需要保证:同一类型的对象,在spring容器中唯一。如果不唯一,会报不唯一的异常

NoUniqueBeanDefinitionException

测试:
1.将user的bean配置修改一下 : autowire=“byType”
2.测试,正常输出
3.在注册一个cat 的bean对象

<bean id="dog" class="com.redeemi.pojo.Dog"/>
<bean id="cat" class="com.redeemi.pojo.Cat"/>
<bean id="cat2" class="com.redeemi.pojo.Cat"/>

<bean id="user" class="com.redeemi.pojo.User" autowire="byType">
   <property name="str" value="张三"/>
</bean>

4.测试,报错:NoUniqueBeanDefinitionException
5.删掉cat2,将cat的bean名称改掉,测试,因为是按类型装配,所以并不会报异常,也不影响最后的结果。甚至将id属性去掉,也不影响结果。

   <!--
    byType:会自动在容器上下文中查找,和自己对象属性类型相同的bean!
        -->
    <bean id="people" class="com.redeemi.pojo.People" autowire="byType">
        <property name="name" value="张三"/>
    </bean>

小结:

  • ByName的时候,需要保证所有bean的id唯一,并且这个bean需要和自动注入的属性的set方法的值一致
  • ByType的时候,需要保证所有bean的class唯一,并且这个bean需要和自动注入的属性的类型一致

3.使用注解实现自动装配

jdk1.5支持的注解,Spring2.5就支持注解了

要使用注解须知:

  • 导入约束
  • 配置注解的支持
<?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:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
	        https://www.springframework.org/schema/beans/spring-beans.xsd
	        http://www.springframework.org/schema/context
	        https://www.springframework.org/schema/context/spring-context.xsd">
		
		<!--开启注解的支持    -->
        <context:annotation-config/>
</beans>

@Autowired

  • 直接在属性上使用即可!也可以在set方法上使用
  • 使用Autowired我们就可以不用编写set方法了,前提是你这个自动配置的属性在IOC(Spring)容器中存在,且符合名字ByName
    测试:

1.将User类中的set方法去掉,使用@Autowired注解

public class User {
   @Autowired
   private Cat cat;
   @Autowired
   private Dog dog;
   private String str;

   public Cat getCat() {
       return cat;
  }
   public Dog getDog() {
       return dog;
  }
   public String getStr() {
       return str;
  }
}

2.配置文件

<context:annotation-config/>

<bean id="dog" class="com.redeemi.pojo.Dog"/>
<bean id="cat" class="com.redeemi.pojo.Cat"/>
<bean id="user" class="com.redeemi.pojo.User"/>

3.测试成功
科普:

  • @Nullable 字段标记了了这个注解,说明这个字段可以为null;
public @interface Autowired {
    boolean required() default true;
}

测试代码

public class People {
    //如果显式定义了Autowired的required属性为false,说明这个对象可以为null,否则不允许为空
    @Autowired(required = false)
    private Cat cat;
    @Autowired
    private Dog dog;
    private String name;
}

如果@Autowired自动装配的环境比较复杂,自动装配无法通过一个注解【@Autowired】完成的时候,我们可以使用@Qualifier(value = “xxx”)去配置@Autowired的使用,指定一个唯一的bean对象注入

  • @Autowired是根据类型自动装配的,加上@Qualifier则可以根据byName的方式自动装配
  • @Qualifier不能单独使用

测试实验步骤:
1.配置文件修改内容,保证类型存在对象。且名字不为类的默认名字

<bean id="dog1" class="com.redeemi.pojo.Dog"/>
<bean id="dog2" class="com.redeemi.pojo.Dog"/>
<bean id="cat1" class="com.redeemi.pojo.Cat"/>
<bean id="cat2" class="com.redeemi.pojo.Cat"/>

2.没有加Qualifier测试,直接报错

3.在属性上添加Qualifier注解

@Autowired
@Qualifier(value = "cat2")
private Cat cat;
@Autowired
@Qualifier(value = "dog2")
private Dog dog;

测试成功输出

@Resource

  • @Resource如有指定的name属性,先按该属性进行byName方式查找装配;
  • 其次再进行默认的byName方式进行装配;
  • 如果以上都不成功,则按byType的方式自动装配。
  • 都不成功,则报异常。

实体类:

public class User {
   //如果允许对象为null,设置required = false,默认为true
   @Resource(name = "cat2")
   private Cat cat;
   @Resource
   private Dog dog;
   private String str;
}

beans.xml

<bean id="dog" class="com.redeemi.pojo.Dog"/>
<bean id="cat1" class="com.redeemi.pojo.Cat"/>
<bean id="cat2" class="com.redeemi.pojo.Cat"/>

<bean id="user" class="redeemi.pojo.User"/>

测试结果成功

配置文件2:beans.xml , 删掉cat2

<bean id="dog" class="com.redeemi.pojo.Dog"/>
<bean id="cat1" class="com.redeemi.pojo.Cat"/>

实体类上只保留注解

@Resource
private Cat cat;
@Resource
private Dog dog;

结果OK

结论:先进行byName查找,失败;再进行byType查找,成功

@Resource和@Autowired的区别:

  • 都是用来自动装配的,都可以放在属性字段上
  • @Autowired通过byType的方式实现,而且必须要求这个对象存在【常用】
  • @Resource默认通过byName的方式实现,如果找不到名字,则通过byType实现,如果两个都找不到的情况下,会报错【常用】
  • 执行顺序不同:@Autowired通过byType的方式实现。

4.注解开发

在Spring4之后,要使用注解开发,必须要保证aop的包导入了
在这里插入图片描述
在配置文件当中,还得要引入一个context约束

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

</beans>

我们之前都是使用 bean 的标签进行bean注入,但是实际开发中,我们一般都会使用注解
1.配置扫描哪些包下的注解

<!--指定注解扫描包-->
<context:component-scan base-package="com.redeemi.pojo"/>

2.在指定包下编写类,增加注解

@Component("user")
// 相当于配置文件中 <bean id="user" class="当前注解的类"/>
public class User {
   public String name = "张三";
}

3.测试

@Test
public void test(){
   ApplicationContext applicationContext =
       new ClassPathXmlApplicationContext("beans.xml");
   User user = (User) applicationContext.getBean("user");
   System.out.println(user.name);
}

2.属性注入
使用注解注入属性

1.可以不用提供set方法,直接在直接名上添加@value(“值”)

@Component("user")
// 相当于配置文件中 <bean id="user" class="当前注解的类"/>
public class User {
   @Value("张三")
   // 相当于配置文件中 <property name="name" value="张三"/>
   public String name;
}

2.如果提供了set方法,在set方法上添加@value(“值”);

@Component("user")
public class User {

   public String name;

   @Value("张三")
   public void setName(String name) {
       this.name = name;
  }
}

3.衍生的注解
@Component有几个衍生注解,我们在web开发中,会按照mvc三层架构分层

dao 【@Repository】
service 【@Service】
controller 【@Controller

这四个注解功能都是一样的,都是代表将某个类注册到Spring中,装配Bean
4.自动装配

  • @Autowired:自动装配通过类型,名字。如果Autowired不能唯一自动装配上属性,则需要通过@Qualifier(value =
    “xxx”)去配置。
  • @Nullable 字段标记了了这个注解,说明这个字段可以为null;
  • @Resource:自动装配通过名字,类型。

5.作用域
scope

  • singleton:默认的,Spring会采用单例模式创建这个对象。关闭工厂 ,所有的对象都会销毁。
  • prototype:多例模式。关闭工厂 ,所有的对象不会销毁。内部的垃圾回收机制会回收
@Component
@Scope("singleton")
public class User {

    //相当于  <property name="name" value="张三"/>
    @Value("张三")
    public String name;
}

小结

  • xml与注解:
  • xml更加万能,适用于任何场合!维护简单方便
  • 注解不是自己类使用不了,维护相队复杂
  • xml与注解最佳实践:
  • xml用来管理bean;
  • 注解只负责完成属性的注入;
  • 我们在使用的过程中,只需要注意一个问题:必须让注解生效,就需要开启注解的支持
   <!--指定要扫描的包,这个包下的注解就会生效-->
    <context:component-scan base-package="com.kuang"/>
    <!--开启注解的支持    -->
    <context:annotation-config/>

5.使用Java的方式配置Spring
我们现在要完全不使用Spring的xml配置了,全权交给Java来做。
JavaConfig是Spring的一个子项目,在Spring4之后,它成为了一个核心功能
在这里插入图片描述

实体类

//这里这个注解的意思,就是说明这个类被Spring接管了,注册到了容器中
@Component
public class User {
    private String name;

    public String getName() {
        return name;
    }

    @Value("张三") //属性注入值
    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                '}';
    }
}

配置文件

// 这个也会Spring容器托管,注册到容器中,因为它本来就是一个@Component
// @Configuration代表这是一个配置类,就和我们之前看的beans.xml
@Configuration
@ComponentScan("com.redeemi.pojo")
@Import(redeemiConfig2.class)
public class redeemiConfig {

    // 注册一个bean,就相当于我们之前写的一个bean标签
    // 这个方法的名字,就相当于bean标签中id属性
    // 这个方法的返回值,就相当于bean标签中的class属性
    @Bean
    public User user(){
        return new User(); // 就是返回要注入到bean的对象!
    }
}

测试类

public class MyTest {
    public static void main(String[] args) {

        //如果完全使用了配置类方式去做,我们就只能通过 AnnotationConfig 上下文来获取容器,通过配置类的class对象加载!
        ApplicationContext context = new AnnotationConfigApplicationContext(redeemiConfig.class);

        User user = context.getBean("user", User.class);
        System.out.println(user.getName());
    }
}

这种纯Java的配置方式,在SpringBoot中随处可见


本文链接: http://www.dtmao.cc/news_show_700398.shtml

附件下载

相关教程

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?