五篇教你掌握spring之三:详解Spring的bean以及注解开发

14 篇文章 0 订阅
9 篇文章 0 订阅

详解Spring的bean以及注解开发

各种复杂类型的依赖注入

我们采用一个类的大杂烩的形式,新建一个Student

package com.lwh.pojo;

import java.util.*;

public class Student {
    private String name;
    private Address address;
    private String[] books;
    private List<String> hobbys;
    private Map<String,String> card;
    private Set<String> games;
    private String wife;
    private Properties info;
	//省略tostring,和get,set方法
}

新建一个beans,其中的接受到在注释中写的很清楚,就不再做文字说明

<?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-4.1.xsd">

    <!--
        bean这个标签就代表实例化了一个对象,id代表实例化的名字,class代表实例化类的路径
        property标签代表设置参数,要求实例化的对象里必须有set方法,否则报错,
        其中有俩个属性
        ref代表传入的对象(写已经注册的bean的id)
        value代表传入的值,例如说对象中有一个属性是String类型的,就直接传入值即可
    -->
    <bean id="address" class="com.lwh.pojo.Address"/>
    <bean id="student" class="com.lwh.pojo.Student">
        <!--第一种,普通值注入-->
        <property name="name" value="芜湖"/>

        <!--第二种,引用类型注入-->
        <property name="address" ref="address"/>

        <!--第三种,数组类型注入,array就是数组的意思-->
        <property name="books">
            <array>
                <value>水浒</value>
                <value>三国</value>
                <value>红楼</value>
            </array>
        </property>

        <!--第四种,list类型注入,相当于很多个普通值,就用value标签-->
        <property name="hobbys">
            <list>
                <value>看书</value>
                <value>打豆豆</value>
            </list>
        </property>

        <!--第五种,List注入,map中装的是键值对,第一个是键key,值是第二个-->
        <property name="card">
            <map>
                <entry key="学号" value="20190105865"/>
                <entry key="学籍号" value="213254654651"/>
            </map>
        </property>

        <!--第六种,set注入-->
        <property name="games">
            <set>
                <value>LOL</value>
                <value>dota</value>
            </set>
        </property>

        <!--第七种,空值注入-->
        <property name="wife">
            <null/>
        </property>

        <!--第八种,Properties值注入,类似于数据库连接的Properties-->
        <property name="info">
            <props>
                <prop key="driver">com.mysql.jdbc</prop>
                <prop key="username">root</prop>
                <prop key="password">123456</prop>
            </props>
        </property>
    </bean>

</beans>

拓展之P空间和C空间注入

新建一个User类

package com.lwh.pojo;

public class User {
    private String name;
    private int age;

    public User() {
    }

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

增加beans.xml文件

<?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:c="http://www.springframework.org/schema/c"

       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-4.1.xsd">

    <!--p命名空间注入,需要在beans中引入p,就相当于property-->
    <bean id="user" class="com.lwh.pojo.User" p:name="芜湖" p:age="19"/>

    <!--c空间注入,相当于通过构造器注入:construct-args-->
    <bean id="user2" class="com.lwh.pojo.User" c:name="芜湖" p:age="19"/>
</beans>

Bean的作用域

  • singleton(单例模式)

    这是spring的默认机制,无论到哪个dao里创建user,拿到的都是用一个user,也就是一旦创建就只有一个

    <bean id="user" class="com.lwh.pojo.User" p:name="芜湖" p:age="19" scope="singleton"/>
    
  • prototype(原型模式)

    每一次去getBean的时候都创建一个新的对象

    <bean id="user" class="com.lwh.pojo.User" p:name="芜湖" p:age="19" scope="prototype"/>
    
  • request

  • session

  • application

  • webscoket

Bean的装配

三种装配方式

  • 在XML中显示配置
  • 在java中显示配置
  • 隐式的自动装配bean

测试环境,pojo中有PC,People,Phone,资源文件是beans.xml

PC:

package com.lwh.pojo;

public class PC {
    public void test(){
        System.out.println("我的个人电脑!");
    }
}

People:

package com.lwh.pojo;

public class People {
    private String own;

    public String getOwn() {
        return own;
    }

    public void setOwn(String own) {
        this.own = own;
    }

    private Phone phone;
    private PC pc;

    public Phone getPhone() {
        return phone;
    }

    public void setPhone(Phone phone) {
        this.phone = phone;
    }

    public PC getPc() {
        return pc;
    }

    public void setPc(PC pc) {
        this.pc = pc;
    }
}

Phone:

package com.lwh.pojo;

public class Phone {
    public void test(){
        System.out.println("我的手机!");
    }
}

beans.xml

<?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-4.1.xsd">
    <bean id="pc" class="com.lwh.pojo.PC"/>
    <bean id="phone" class="com.lwh.pojo.Phone"/>

    <bean id="people" class="com.lwh.pojo.People" autowire="byName">
        <property name="own" value="芜湖"/>
    </bean>
</beans>

test:

import com.lwh.pojo.People;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Mytest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        People people = context.getBean("people", People.class);
        people.getPc().test();
        people.getPhone().test();
    }
}

隐式自动装配:

byName就是寻找上下文中,people的set方法后面紧跟着的对象名,例如setPc,那么就会去寻找上下文中是否有叫pc的对象(也就是beanid叫pc的对象),有就自动装配,没有就报空指针异常,如果我讲第一个bean的id改为“pc123454”,那么就会出错

byType就是寻找上下文中,people中与对象类型相同的bean,与id无关,例如,我将第一个bean的id删除,也可以成功,将id改为“pc213234”也能装配成功,但是上下文中不能同时存在要自动装配的对象类型相同的bean,例如如果使用byType自动装配,就不能出现两个pc对象(bean),否则报错

<?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-4.1.xsd">
    <bean class="com.lwh.pojo.PC"/>
    <bean id="phone" class="com.lwh.pojo.Phone"/>

    <bean id="people" class="com.lwh.pojo.People" autowire="byType">
        <property name="own" value="芜湖"/>
    </bean>
</beans>

注解自动装配

需要加入其它约束,结构如下:

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

    <context:annotation-config/>
</beans>
  • @Autowired

    直接在属性上使用,也可以在set方法上使用,如果使用注解自动装配,我们可以不编写Set方法,前提是你这个自动装配的属性在IOC容器中要存在,切符合名字byname(也就是和使用byname装配的前提一致)

package com.lwh.pojo;

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

public class People {
   private String own;
   @Autowired
   private Phone phone;
   @Autowired
   private PC pc;

   public String getOwn() {
       return own;
   }

   public void setOwn(String own) {
       this.own = own;
   }

   
   public Phone getPhone() {
       return phone;
   }


   public PC getPc() {
       return pc;
   }

}
@Autowired(value=false)//代表可以将属性设置为null

那么如果我想创建多个相同类型的bean,但是还想要people自动装配怎么办?

  • @Qualifier

    这个注解可以指定id装配

      @Autowired
      @Qualifier(value = "pc1234")
      private PC pc;
    

    然后在beans中有

    <bean id="pc1234" class="com.lwh.pojo.PC"/>
    <bean id="pc123" class="com.lwh.pojo.PC"/>
    
  • @Resource

    • 都可以与Autowired一样用于属性字段上自动装配
    • @Autowired通过byType的方法实现
    • @Resource默认通过byname的方式实现,如果找不到就使用byType如果两个都找不到就报错

使用注解开发

bean的注解注入

@Component注解

  • beans.xml中导入依赖支持、
 <?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-4.1.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-4.1.xsd">

    <!--代表去扫描com.lwh.pojo下的类-->
    <context:component-scan base-package="com.lwh.pojo"/>
    <context:annotation-config/>

</beans>
  • 类中加入注解
  package com.lwh.pojo;

import org.springframework.stereotype.Component;

//这个注解就相当于<bean id="user" class="com.lwh.pojo.User/>
@Component
public class User {
    public String name="芜湖";
}

属性的注解注入

@Value(可以用在属性或者set方法上)

package com.lwh.pojo;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

//这个注解就相当于<bean id="user" class="com.lwh.pojo.User/>
@Component
public class User {
    @Value("芜湖")//设置属性值
    public String name;
}

衍生注解

@Component有几个衍生注解,会按照mvc三层架构分层

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

其实本质都是一样的,都是代表某个类去注册到Spring中,装配Bean

自动装配置

  • @Autowired

  • @Qualifier

  • @Resource

作用域

package com.lwh.pojo;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

//这个注解就相当于<bean id="user" class="com.lwh.pojo.User/>
@Component
@Scope("prototype")//原型模式,从bean容器中取一次就new一个新的对象
public class User {
    @Value("芜湖")//设置属性值
    public String name;
}

JavaConfig注解开发

采用纯java代码的形式配置spring,不再使用xml形式,新建一个子项目,代码结构如下:

在这里插入图片描述

config.java:

加入**@Configuration注解,代表这是一个java代码的config注册类,再注册一个bean,采用@Bean**注解,

package com.lwh.config;

import com.lwh.pojo.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan("com.lwh.pojo")//就相当于扫描实体类
public class Config {

    //以下语句就相当于<bean id="getUser" class="com.lwh.pojo.User"/>
    //bean的id就是方法名,大小写区分
    @Bean
    public User getUser(){
        return new User();
    }
}

User.java

采用**@Component**自动准备bean,然后再往set方法上注入name值为“芜湖”

package com.lwh.pojo;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class User{
    private String name;

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

    public String getName() {
        return name;
    }

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

Test.java

import com.lwh.config.Config;
import com.lwh.pojo.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Test {
    public static void main(String[] args) {
        //注意!这里使用AnnotationConfigApplicationContext
        ApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
        User user = context.getBean("getUser", User.class);
        System.out.println(user.getName() );
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值