一、什么是JavaBean

 

 

  JavaBean是一个遵循特定写法的Java类,它通常具有如下特点:

  • 这个Java类必须具有一个无参的构造函数
  • 属性必须私有化。
  •  
  • 私有化的属性必须通过public类型的方法暴露给其它程序,并且方法的命名也必须遵守一定的命名规范。


  • 一、Bean是啥

    1、Java面向对象,对象有方法和属性,那么就需要对象实例来调用方法和属性(即实例化);

     

    2、凡是有方法或属性的类都需要实例化,这样才能具象化去使用这些方法和属性;

     

    3、规律:凡是子类及带有方法或属性的类都要加上注册Bean到Spring IoC的注解;(@Component , @Repository , @ Controller , @Service , @Configration)

     

    4、把Bean理解为类的代理或代言人(实际上确实是通过反射、代理来实现的),这样它就能代表类拥有该拥有的东西了

     

    5、我们都在微博上@过某某,对方会优先看到这条信息,并给你反馈,那么在Spring中,你标识一个@符号,那么Spring就会来看看,并且从这里拿到一个Bean(注册)或者给出一个Bean(使用)


    二、注解分为两类:

    1、一类是使用Bean,即是把已经在xml文件中配置好的Bean拿来用,完成属性、方法的组装;比如@Autowired , @Resource,可以通过byTYPE(@Autowired)、byNAME(@Resource)的方式获取Bean;

     

    2、一类是注册Bean,@Component , @Repository , @ Controller , @Service , @Configration这些注解都是把你要实例化的对象转化成一个Bean,放在IoC容器中,等你要用的时候,它会和上面的@Autowired , @Resource配合到一起,把对象、属性、方法完美组装。

     

    什么是Bean?

    Spring Bean是被实例的,组装的及被Spring 容器管理的Java对象。

    Spring 容器会自动完成@bean对象的实例化。

    创建应用对象之间的协作关系的行为称为:装配(wiring),这就是依赖注入的本质。

    Spring 三种配置方案

    1.在XML中进行显示配置
    2.使用Java代码进行显示配置
    3.隐式的bean发现机制和自动装配
    推荐方式: 3>2>1

    一、自动化装配bean

    1.组件扫描(component scanning):Spring 会自动发现应用上下文中所创建的bean。
    2.自动装配(autowiring):Spring自动满足bean之间的依赖。

     
    1. package com.stalkers;

    2.  
    3. /**

    4. * CD唱片接口

    5. * Created by stalkers on 2016/11/17.

    6. */

    7. public interface ICompactDisc {

    8. void play();

    9. }

     
    1. package com.stalkers.impl;

    2.  
    3. import com.stalkers.ICompactDisc;

    4. import org.springframework.stereotype.Component;

    5.  
    6. /**

    7. * Jay同名专辑

    8. * Created by stalkers on 2016/11/17.

    9. */

    10. @Component

    11. public class JayDisc implements ICompactDisc {

    12.  
    13. private String title = "星晴";

    14.  
    15. public void play() {

    16. System.out.println(title + ":一步两步三步四步,望着天上星星...");

    17. }

    18. }

    Component注解作用:
    表明该类会作为组件类。

    不过,组件扫描默认是不开启用的,我们还需要显示配置下Spring,从而命令它去寻找带有@Component注解的类,并为其创建bean。

    1.java code开启组件扫描:
    其中,如果CompoentScan后面没有参数的话,默认会扫描与配置类相同的包

     
    1. @Configuration

    2. @ComponentScan

    3. public class CDPlayerConfig {

    4. @Bean

    5. public ICompactDisc disc() {

    6. return new JayDisc();

    7. }

    8. }

    2.xml启动组件扫描

     
    1. <?xml version="1.0" encoding="utf-8" ?>

    2. <beans xmlns="http://www.springframework.org/schema/beans"

    3. xmlns:context="http://www.springframework.org/schema/context"

    4. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    5. xsi:schemaLocation="http://www.springframework.org/schema/context

    6. http://www.springframework.org/schema/context/spring-context.xsd">

    7. <context:component-scan base-package="com.stalkers.impl"/>

    8. </beans>

    测试代码

     
    1. package com.stalkers;

    2.  
    3. import com.stalkers.config.CDPlayerConfig;

    4. import org.junit.Test;

    5. import org.junit.runner.RunWith;

    6. import org.springframework.beans.factory.annotation.Autowired;

    7. import org.springframework.test.context.ContextConfiguration;

    8. import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

    9.  
    10. /**

    11. * Created by stalkers on 2016/11/18.

    12. */

    13. @RunWith(SpringJUnit4ClassRunner.class)

    14. @ContextConfiguration(classes = CDPlayerConfig.class)

    15. public class TestPlay {

    16. @Autowired

    17. private ICompactDisc jayDisc;

    18.  
    19. @Test

    20. public void play() {

    21. jayDisc.play();

    22. }

    23. }

    在ComponentScan扫描的包中,所有带有@Component注解的类都会创建为bean

    为组件扫描的bean命名

    Spring应用上下文种所有的bean都会给定一个ID。在前面的例子中,尽管我们没有明确地为JayDisc bean设置ID,但是Spring会默认为JayDisc设置ID为jayDisc,也就是将类名的第一个字母变成小写。

    如果想为这个bean设置不同的ID,那就将期望的值传递给@Component注解

     
    1. @Component("zhoujielun")

    2. public class JayDisc implements ICompactDisc {

    3. ...

    4. }

    如果不使用@Component注解的话,则使用Java依赖注入规范(Java Dependency Injection)中所提供的@Named注解bean的ID。

    需要引入:

     
    1. <dependency>

    2. <groupId>javax.inject</groupId>

    3. <artifactId>javax.inject</artifactId>

    4. <version>1</version>

    5. </dependency>

     
    1. @Named("zhoujielun")

    2. public class JayDisc implements ICompactDisc {

    3. ....

    4. }

    设置组件扫描的基础包

    前面再给CDPlayerConfig类设置@ComponentScan,我们并没有设置任何属性,这个时候默认扫描默认包是:CDPlayerConfig类所在包及其包的子包。

    如果是下图这种情况,DisConfig与其这时候就需要设置@ComponentScan的扫描的包。

    image

     
    1. @Configuration

    2. @ComponentScan(basePackages = {"com.stalkers.soundsystem"})

    3. public class DiscConfig {

    4. }

    basePackages使用的是复数,则意味着可以设置多个基础包。

    但是basePackages后面跟的是String类型,这种类型并不安全。可以使用basePackageClasses有下面这种写法:

     
    1. @Configuration

    2. @ComponentScan(basePackageClasses = {com.stalkers.soundsystem.JayCompactDisc.class})

    3. public class DiscConfig {

    4. }

    通过为bean添加注解实现自动装配

    如果所有的对象都是独立的,彼此之间没有任何依赖,那么使用组件扫描就能自动化装配bean。

    但是实际工作中,很多对象会依赖其他对象完成任务。这时候就需要能够将组件扫描得到的bean和他们依赖装配在一起。这就是自动装配(autowiring)

    使用Spring的Autowired

     
    1. public interface IMediaPlayer {

    2. void play();

    3. }

     
    1. @Component

    2. public class CDPlayer implements IMediaPlayer {

    3.  
    4. private ICompactDisc cd;

    5.  
    6. @Autowired

    7. public CDPlayer(ICompactDisc cd) {

    8. this.cd = cd;

    9. }

    10.  
    11. public void play() {

    12. System.out.println("cd Play:");

    13. cd.play();

    14. }

    15. }

    CDPlayer类的构造器上添加了@Autowired注解,表明当Spring创建CDPlayerbean的时候,会通过这个构造器来进行实例化

    Autowired的多种方式
    1.构造器注解(constructor)

    2.属性setter注解

    3.field注解

    不管使用上面3中的哪个方法,Spring都会满足声明的依赖。假如有且只有一个bean匹配依赖的话,那么这个bean将会被装配进来。

    如果使用2,3方式注解,有多个bean的话,则用Qualifier指定。

    如果没有匹配的bean,那么在应用上下文创建的时候,Spring会抛出一个异常。为了避免异常的出现,可以使用

     
    1. @Autowired(required = false)

    2. private IMediaPlayer CDPlayer;

    required=false表示如果没有匹配的话,Spring会让bean处于未装配的样子。使用未装配的属性,会出现NullPointerException

    总结:
    所以在使用开发的时候一般建议使用Resource(package javax.annotation)进行注解。但是Resource不支持构造器注解

    二、通过Java代码装配Bean

    尽管在很多场景下通过组件扫描和自动装配实现Spring的自动化更为推荐,但是有时候行不通。比如引用第三方组件,没办法在它的类上添加@Component及@Autowired。所以就需要JavaConfig或者XML配置

    在进行显示配置的时候,JavaConfig是更好的解决方案。

    JavaConfig与其他的Java代码又有所区别,在概念上它与应用程序中的业务逻辑和领域代码又有所不同。JavaConfig是配置相关代码,不含任何逻辑代码。通常会将JavaConfig放到单独的包中。

    创建JavaConfig类

     
    1. @Configuration

    2. public class CDPlayerConfig {

    3. }

    使用@Configuration表明CDPlayerConfig是一个配置类

    声明简单的bean

     
    1. @Bean

    2. public IMediaPlayer cdplayer() {

    3. return new VCDPlayer(new JayCompactDisc());

    4. }

    @Bean注解会告诉Spring将返回一个对象。

    默认情况下,@Bean的Id与带有@Bean的方法名一样。当然也可以通过@Bean的name属性指定额外的方法名。

    借助JavaConfig注入

    在上面的例子中,初始化个VCDPlayer都需要new一个JayCompactDisc对象。如果其他的对象的也需要JayCompactDisc,所以优化如下:

     
    1. @Bean

    2. public IMediaPlayer cdplayer() {

    3. return new VCDPlayer(disc());

    4. }

    5.  
    6. @Bean

    7. public ICompactDisc disc() {

    8. return new JayCompactDisc();

    9. }

    单独抽出disc()方法,在其方法上加上Bean注解,Spring上加@Bean注解的都是默认单例模式,不管disc()被多个方法调用,其disc()都是同一个实例。

    当然上面的初始化可以优化如下:

     
    1. @Bean

    2. public IMediaPlayer cdplayer(ICompactDisc disc) {

    3. return new VCDPlayer(disc);

    4. }

    三、通过XML装配Bean

    在xml配置中,创建一个xml文件,并且要以元素为根。

     
    1. <?xml version="1.0" encoding="utf-8" ?>

    2. <beans xmlns="http://www.springframework.org/schema/beans"

    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    4. xsi:schemaLocation="http://www.springframework.org/schema/beans

    5. http://www.springframework.org/schema/beans/spring-beans.xsd">

    6.  
    7. </beans>

    在使用xml的时候,需要在配置文件顶部声明多个xml模式(XML Schema Definition xsd)文件

    对于我们需要配置bean的则在spring-beans模式中。

     
    1. <?xml version="1.0" encoding="utf-8" ?>

    2. <beans xmlns="http://www.springframework.org/schema/beans"

    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    4. xsi:schemaLocation="http://www.springframework.org/schema/beans

    5. http://www.springframework.org/schema/beans/spring-beans.xsd">

    6. <bean id="jayCompactDisc" class="com.stalkers.soundsystem.JayCompactDisc"></bean>

    7. </beans>

    1.借助构造器注入初始化bean

    构造器注入的方案:
    1.元素

     
    1. <?xml version="1.0" encoding="utf-8" ?>

    2. <beans xmlns="http://www.springframework.org/schema/beans"

    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    4. xsi:schemaLocation="http://www.springframework.org/schema/beans

    5. http://www.springframework.org/schema/beans/spring-beans.xsd">

    6. <bean id="jayCompactDisc" class="com.stalkers.soundsystem.JayCompactDisc"></bean>

    7. <bean id="cdPlayer" class="com.stalkers.soundsystem.VCDPlayer">

    8. <constructor-arg ref="jayCompactDisc"/>

    9. </bean>

    10. </beans>

    2.使用Spring3.0所引入的c-命名空间

    使用c-命名空间,需要引入:

    xmlns:c="http://www.springframework.org/schema/c"
     
    1. <?xml version="1.0" encoding="utf-8" ?>

    2. <beans xmlns="http://www.springframework.org/schema/beans"

    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    4. xmlns:c="http://www.springframework.org/schema/c"

    5. xsi:schemaLocation="http://www.springframework.org/schema/beans

    6. http://www.springframework.org/schema/beans/spring-beans.xsd">

    7. <bean id="jayCompactDisc" class="com.stalkers.soundsystem.JayCompactDisc"></bean>

    8. <bean id="cdPlayer" class="com.stalkers.soundsystem.VCDPlayer" c:cd-ref="jayCompactDisc">

    9. </bean>

    10. </beans>

    解析:c-命名空间的语法:

    c:cd-ref="jayCompactDisc"

    1.c 代表命名空间前缀

    2.cd 代表VCDPlayer类的构造器参数名。当然我们也可以使用参数在整个参数列表的位置 c:_0-ref

     <bean id="cdPlayer" class="com.stalkers.soundsystem.VCDPlayer" c:_0-ref="jayCompactDisc">

    使用下划线因为参数不能以数字开头,所以加下划线。

    3.-ref 代表注入bean引用

    4.jayCompactDisc 要注入的bean的id

    注意:

    c-命名需要写在标签内,与constructor-arg写法差别很大

    将字面量注入到构造器中

    上面我们所做的DI通常指的是类型的装配,也就是将对象的引用装配到依赖他们的其他对象中,但是有时候我们传的只是一个字面量值

     
    1. public class VaeCompactDisc implements ICompactDisc {

    2. private String title;

    3.  
    4. public VaeCompactDisc(String title) {

    5. this.title = title;

    6. }

    7.  
    8. public void play() {

    9. System.out.println("大家好,我是Vae,下面这首:" + title + "献给大家的");

    10. }

    11. }

     
    1. <bean id="cdPlayer" class="com.stalkers.soundsystem.VCDPlayer" c:_0-ref="vaeCompactDisc">

    2. </bean>

    3. <bean id="vaeCompactDisc" class="com.stalkers.soundsystem.VaeCompactDisc">

    4. <constructor-arg value="浅唱"></constructor-arg>

    5. </bean>

    c-命名空间的写法

     
    1. <bean id="cdPlayer" class="com.stalkers.soundsystem.VCDPlayer" c:_0-ref="vaeCompactDisc">

    2. </bean>

    3. <bean id="vaeCompactDisc" class="com.stalkers.soundsystem.VaeCompactDisc" c:title="城府">

    4. <!--<constructor-arg value="浅唱"></constructor-arg>-->

    5. </bean>

    装配集合

     
    1. public class VaeCompactDisc implements ICompactDisc {

    2. private String title;

    3.  
    4. private List<String> tracks;

    5.  
    6. public VaeCompactDisc(String title, List<String> tracks) {

    7. this.title = title;

    8. this.tracks = tracks;

    9. }

    10.  
    11. public void play() {

    12. System.out.println("大家好,我是Vae,下面这专辑:" + title + "献给大家的");

    13. for (String s : tracks) {

    14. System.out.println(s);

    15. }

    16. }

    17. }

    Spring配置使用constructor-arg。而c-命名的是无法使用装配集合的功能

     
    1. <bean id="cdPlayer" class="com.stalkers.soundsystem.VCDPlayer" c:_0-ref="vaeCompactDisc">

    2. </bean>

    3. <bean id="vaeCompactDisc" class="com.stalkers.soundsystem.VaeCompactDisc">

    4. <constructor-arg name="title" value="自定义"></constructor-arg>

    5. <constructor-arg name="tracks">

    6. <list>

    7. <value>有何不可</value>

    8. <value>多余的解释</value>

    9. </list>

    10. </constructor-arg>

    11. </bean>

    2.使用属性Setter方法注入

     
    1. public class CDPlayer implements IMediaPlayer {

    2.  
    3. private ICompactDisc cd;

    4.  
    5. @Autowired

    6. public void setCd(ICompactDisc cd) {

    7. this.cd = cd;

    8. }

    9.  
    10. public CDPlayer(ICompactDisc cd) {

    11. this.cd = cd;

    12. }

    13.  
    14. public void play() {

    15. System.out.println("cd Play:");

    16. cd.play();

    17. }

    18. }

    Spring.xml配置里面

     
    1. <bean id="cdPlayer" class="com.stalkers.soundsystem.VCDPlayer">

    2. <property name="cd" ref="jayCompactDisc"></property>

    3. </bean>

    元素为属性的Setter方法所提供的功能与元素为构造器所提供的功能是一样的。

    与c-命名空间的类似的作为property的替代方案:p-命名空间。使用p-命名空间需要引入:

    xmlns:p="http://www.springframework.org/schema/p"

    Spring.xml配置如下

    <bean id="cdPlayer" class="com.stalkers.soundsystem.VCDPlayer" p:cd-ref="vaeCompactDisc">

    语法解析:

    p:cd-ref="vaeCompactDisc"

    1.p-:命名空间的前缀

    2.cd:属性名称

    3.-ref:注入bean引用

    4.vaeCompactDisc:所注入的bean的id

    将字面量注入到属性中

    字面量注入到属性与上面将字面量注入到构造方法中方式一样。只不过标签名改成了property。

    装配list也是与上面的构造器的装配list一样。

    虽然我们无法使用c-及p-命名空间装配list,但是我们可以使用

     
    1. <bean id="vaeCompactDisc" class="com.stalkers.soundsystem.VaeCompactDisc" c:title="自定义" c:tracks-ref="songs">

    2. </bean>

    3. <util:list id="songs">

    4. <value>有何不可</value>

    5. <value>多余的解释</value>

    6. </util:list>

    Spring util命名空间的中的元素:

    元素描述
    util:constant引用某个类型的public static 域
    util:list创建一个java.util.List类型的bean,其中包含值或引用
    util:map创建一个java.util.Map类型的bean,其中包含值或引用
    util:properties创建一个java.util.Properties类型的bean
    util:property-path引用一个bean的属性
    util: set创建一个java.util.Set类型的bean

    在此我向大家推荐一个架构学习交流群。交流学习群号:895244712 里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化、分布式架构等这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

    四、导入和混合配置

    在Spring应用中,我们可以同时使用自动化和显示配置。

    如果一个JavaConfig配置太臃肿,我们可以把其进行拆分,然后使用@Import将拆分的类进行组合。

    如果希望在JavaConfig里引用xml配置。则可以使用@ImportResource

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值