Spring菜鸟小白学习笔记-----Spring属性注入------详细源码和解析!

一个物欲横流的世界
是资本使你变坏还是?
               ---致多人运动运动员,时间管理家...

上一节我们说到
Spring工厂类,今天的代码也是基于上次的项目内的demo4和demo5不清楚的同学点下方链接去看下。

具体地址

学习笔记的目录

在此

今天来说下Spring属性注入的问题

Spring的属性注入
1、Spring给类注入属性
为此我们需要在demo4下创建如下的类
在这里插入图片描述
一点一点来,不要着急我们首先看

SpringDemo4是测试类
Spring的属性注入(XML方式)
支持构造函数注入

通过构造方法注入Bean的属性值或依赖的对象,它保证了Bean的实例在实例化后就可以使用
构造器注入在元素里声明的属性
我们首先创建User类来测试构造函数注入

public class User {
    private String name;
    private Integer age;
    public User(String n,Integer a){
        name=n;
        age=a;
    }

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

为此我们在Spring配置文件中加载的配置文件是

 <!--Bean的构造方法的属性注入-->
    <bean id="user" class="com.imooc.ioc.demo4.User">
        <constructor-arg name="n" value="jjyu-God"  />
        <constructor-arg name="a" value="22"/>
    </bean>

然后测试类的第一个方法为

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

测试效果
在这里插入图片描述

下一个需要测试的是

属性setter方法注入

使用set方法注入,在Spring配置文件中,通过设置注入的属性,普通类型用value,对象类型用ref。
我们为此创建两个类cat和person类
代码如下

public class Cat {
    private String name;

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
public class Person {
    private String name;
    private Integer age;

    private Cat cat;

    public Cat getCat() {
        return cat;
    }

    public void setCat(Cat cat) {
        this.cat = cat;
    }

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

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

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

对应的Spring配置文件为

<!--Bean的set方法的属性注入-->
    <bean id="person" class="com.imooc.ioc.demo4.Person">
        <property name="age" value="188"/>
        <property name="name" value="GOD"/>
        <property name="cat" ref="cat"/>
    </bean>
    <bean id="cat" class="com.imooc.ioc.demo4.Cat">
        <property name="name" value="JIIJIJIJIJ"/>
    </bean>

对应的测试类的方法

    @Test
    public void demo2(){
        ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
        Person person=(Person) applicationContext.getBean("person");
        System.out.println(person);
    }

在这里插入图片描述

p名称空间

使用P命名空间
为了简化XML文件配置,p:<属性名>="xxx"引入常量值 p:<属性名>-ref="xxx"引用七天bean对象
这个用到的类和测试方法都是和属性setter方法注入一样的,所以不再重复
但是配置文件中把上一个给注释掉,加上

    <bean id="person" class="com.imooc.ioc.demo4.Person" p:name="skosko" p:age="330" p:cat-ref="cat"/>
    <bean id="cat" class="com.imooc.ioc.demo4.Cat" p:name="dog_cat"/>

效果
在这里插入图片描述

SpELl注入

SpEL:Spring expression language,Spring表达式语言,对依赖注入进行简化
语法:#{表达式}
SpEL 表达式语言
#{‘hello’}:使用字符串
#{beanId}:使用另一个bean
#{beanId,content.toUpperCase()}:使用指定名属性,并使用方法
#{T(java.lang.Math).PI}:使用静态字段或方法
还是在demo4这个包下
我们创建Category和product和productinfo这三个类
具体代码

public class Catagory {
    private String name;

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
public class productInfo {
    public Double calculatePrice(){
        return Math.random()*199;
    }
}
public class Product {
    private String name;
    private Double price;

    private Catagory catagory;

    @Override
    public String toString() {
        return "Product{" +
                "name='" + name + '\'' +
                ", price=" + price +
                ", catagory=" + catagory +
                '}';
    }

    public String getName() {
        return name;
    }

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

    public Double getPrice() {
        return price;
    }

    public void setPrice(Double price) {
        this.price = price;
    }

    public Catagory getCatagory() {
        return catagory;
    }

    public void setCatagory(Catagory catagory) {
        this.catagory = catagory;
    }
}

对应的配置文件

    <!--SpEL的属性注入-->
<bean id="category" class="com.imooc.ioc.demo4.Catagory">
    <property name="name" value="#{'服装'}"/>
</bean>
    <bean id="productInfo" class="com.imooc.ioc.demo4.productInfo"/>
    <bean id="product" class="com.imooc.ioc.demo4.Product">
        <property name="catagory" value="#{category}"/>
        <property name="name" value="#{'asdaaaaaaa'}"/>
        <property name="price" value="#{productInfo.calculatePrice()}"/>
    </bean>

测试方法

 @Test
    public void demo3(){
        ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
        Product product=(Product) applicationContext.getBean("product");
        System.out.println(product);
    }

在这里插入图片描述

复杂类型的属性注入

数组类型的属性注入
List集合类型的属性注入
Set集合类型的属性注入
Map集合类型的属性注入
Properties类型的属性注入
对于类成员变量,注入方式有三种
构造函数注入
属性setter方法注入
接口注入

我们在demo5 下面创建如下方法
在这里插入图片描述
首先创建CollectionBean
具体代码

public class CollectionBean {
    private String[] arrs;//数组类型

    private List<String> list;

    private Set<String> set;

    private Map<String ,Integer> map;

    private Properties properties;

    @Override
    public String toString() {
        return "CollectionBean{" +
                "arrs=" + Arrays.toString(arrs) +
                ", list=" + list +
                ", set=" + set +
                ", map=" + map +
                ", properties=" + properties +
                '}';
    }

    public String[] getArrs() {
        return arrs;
    }

    public void setArrs(String[] arrs) {
        this.arrs = arrs;
    }

    public List<String> getList() {
        return list;
    }

    public void setList(List<String> list) {
        this.list = list;
    }

    public Set<String> getSet() {
        return set;
    }

    public void setSet(Set<String> set) {
        this.set = set;
    }

    public Map<String, Integer> getMap() {
        return map;
    }

    public void setMap(Map<String, Integer> map) {
        this.map = map;
    }

    public Properties getProperties() {
        return properties;
    }

    public void setProperties(Properties properties) {
        this.properties = properties;
    }
}

对应的Spring的配置

<!--集合类型的属性注入-->
    <bean id="collectionBean" class="com.imooc.ioc.demo5.CollectionBean">
        <!--数组类型-->
        <property name="arrs">
            <list>
                <value>aaa</value>
                <value>bbbb</value>
                <value>ccccccc</value>
            </list>
        </property>
        <!--列表类型-->
        <property name="list">
            <list>
                <value>111111</value>
                <value>222a</value>
                <value>333a</value>
            </list>
        </property>
        <!--Set集合类型-->
        <property name="set">
           <set>
               <value>delete</value>
               <value>delete</value>
               <value>delete1</value>
               <value>delete2</value>
           </set>
        </property>
        <!--Map类型-->
        <property name="map">
            <map>
                <entry key="a" value="12"></entry>
                <entry key="b" value="22"></entry>
                <entry key="c" value="32"></entry>
            </map>
        </property>
        <!--属性类型-->
        <property name="properties">
            <props>
                <prop key="username">root</prop>
                <prop key="passwoord">123556</prop>
            </props>
        </property>
    </bean>

对应的测试方法SpringDemo5

public class SpringDemo5 {
    @Test
    public void demo1(){
        ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
       CollectionBean collectionBean=(CollectionBean) applicationContext.getBean("collectionBean");
        System.out.println(collectionBean.toString());
    }
}

在这里插入图片描述

Spring的Bean管理(注解方式)

在此中,为了不至于和以上demo1-demo5发生冲突
我们新建一个项目,新建方式在
项目名推荐为Spring_ioc_annotation
此链接

创建好之后我们的项目结构如下
在这里插入图片描述

@Component描述Spring框架中Bean
下面这三个是将开发变得更加清晰
@Repository用于DAO实现类进行标注
@Service 用于对Service实现类进行标注
@Controller用于对Controller实现类进行标注

注解方式属性注入
@Value()对单一属性
有setter方法加在setter方法上,没有setter方法,则加在属性上
@Autowired()进行自动注入
@Autowired默认按照类型进行注入
如果存在两个相同的Bean类型相同,则按照名称注入,注入时可以针对成员变量或者set方法
通过@Autowired的required属性,设置一定要找到匹配的Bean
使用@Qualifiler指定注入Bean的名称
@Resource==@Autowired和@Qualifiler之和
对于我们首先在demo1中配置如下类
在这里插入图片描述
首先是UserDao和UserService
其具体代码如下

@Repository("userDao1")
public class UserDao {
    public void save(){
        System.out.println("DAO保存用户");
    }
}
/**
 * SpringBean管理的注解方式
 * 传统方式是去XML中配置<bean id="" class=""/>
 *
 */
//@Component("userService")
    @Service("userService")
public class UserService {
    @Value("米饭")
    private String something;

//    @Autowired
//    @Qualifier("userDao1")
    @Resource(name = "userDao1")
    private UserDao userDao;
    public void eat(){
        System.out.println("eat+" +something);
    }
    public String sayHello(String name){
        return "hello "+name;
    }

    public void save(){
        System.out.println("Service中保存用户的方法");
        userDao.save();
    }
}

Spring配置文件

<!--开启注解扫描 ,把多数注解方式都打开了-->
    <context:component-scan base-package="com.jjyu"/>
    
    <!--单独使用属性注入的注解-->
    <context:annotation-config/>

测试方法SpringDemo1
详细代码

public class SpringDemo1 {
    @Test
    public void demo1(){
        ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService=(UserService) applicationContext.getBean("userService");
        String s=userService.sayHello("GOD");
        System.out.println(s);
    }
    @Test
    public void demo2(){
        ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService=(UserService) applicationContext.getBean("userService");

       userService.eat();
    }

    @Test
    public void demo3(){
        ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService=(UserService) applicationContext.getBean("userService");

        userService.save();
    }

}

在这里插入图片描述

Spring的其他注解
Spring初始化Bean和销毁bean时,有时需要做一些处理工作,因此Spring可以在创建和拆卸bean的时候调用bean的两个生命周期方法
当Bean被载入到容器的时候调用init
注解方法:@PostConstruct初始化
当bean从容器中删除的时候调用destory(scope=singleton有效)
注解方法:@PreDestory 销毁
Bean的作用范围
使用注解配置的Bean和配置的一样,默认作用范围都是singleton
@Scope注解用于指定Bean的作用范围
在Demo2中建立如下类
在这里插入图片描述
对于Bean1和Bean2代码如下

@Component("bean1")
public class Bean1 {
    @PostConstruct
    public void init(){
        System.out.println("init bean........");
    }
    public  void  say(){

        System.out.println("Bean1 say.........");
    }
    @PreDestroy
    public  void destroy(){
        System.out.println("destroy bean1  ......");
    }
}
@Component("bean2")
@Scope("prototype")
public class Bean2 {

}

Spring配置无需改动,上面就开启了自动扫描
测试类代码SpringDemo2

public class SpringDemo2 {

    @Test
    public void demo1(){
        ClassPathXmlApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
        Bean1 bean1=(Bean1)applicationContext.getBean("bean1");
        bean1.say();
        applicationContext.close();
    }
    @Test
    public void demo2(){
        ClassPathXmlApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
        Bean2 bean2=(Bean2)applicationContext.getBean("bean2");
        Bean2 bean22=(Bean2)applicationContext.getBean("bean2");
        System.out.println(bean2);
        System.out.println(bean22);


    }

}

效果
在这里插入图片描述

传统XML配置和注解配置混合使用
XML优势:管理类
结构清晰,易于阅读
注解方式的优势:属性注入
开发便捷,属性注入方便
XML和注解的整合开发
1、引入Context命名空间
2、在配置文件中添加Context:annotation-config标签
整合开发
在demo3这个包
在这里插入图片描述
CatagoryDao和ProductDao和ProductService
代码如下

public class CatagoryDao {
    public void save(){
        System.out.println("Catagory save/");
    }
}
public class ProductDao {
    public void save(){
        System.out.println("productDao save/");
    }
}
public class ProductService {

    @Resource(name="catagoryDao")
    private CatagoryDao catagoryDao;

    @Resource(name = "productDao")
    private ProductDao productDao;


//    public void setCatagoryDao(CatagoryDao catagoryDao) {
//        this.catagoryDao = catagoryDao;
//    }
//
//    public void setProductDao(ProductDao productDao) {
//        this.productDao = productDao;
//    }

    public void save(){

        System.out.println("product service save.........");
        catagoryDao.save();
        productDao.save();
    }
}

Spring中配置

   <bean id="productService" class="com.jjyu.demo3.ProductService">
        <!--<property name="productDao" ref="productDao"/>-->
        <!--<property name="catagoryDao" ref="categoryDao"/>-->
    </bean>

    <bean id="productDao" class="com.jjyu.demo3.ProductDao"/>

    <bean id="catagoryDao" class="com.jjyu.demo3.CatagoryDao"/>

SpringDemo4的代码

public class SpringDemo4 {
  @Test
    public void demo1(){
      ClassPathXmlApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
      ProductService productService=(ProductService)applicationContext.getBean("productService");
      productService.save();
  }
}

在这里插入图片描述
ok,
还请返回继续学习下一节

在此

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值