栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

SpringIOC

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SpringIOC

ioc有参构造注入

spring-beans约束文件




引入Lombok


    org.projectlombok
    lombok
    1.18.16

有参构造方法

@AllArgsConstructor
public class Person {
    private Integer id;
    private String name;
    public void sayHello(String name){
        System.out.println(this.id+this.name+" say hello to " + name);
    }
}

注册bean




    
        
        
        
    

测试类

public class IocTest {
    public static void main(String[] args) {
        ApplicationContext ctx=new ClassPathXmlApplicationContext("spring-ioc-cfg.xml");
        Person person = (Person) ctx.getBean("Person");
        person.sayHello("luyi");
    }
}

测试结果

1at say hello to tt
有参构造方法注入缺陷
public class Person {
    private Integer id;
    private String name;
    private String nickname;

    public Person(String name, String nickname) {
        this.name = name;
        this.nickname = nickname;
    }

    public Person(Integer id, String name) {
        this.id = id;
        this.name = name;
    }

    public void sayHello(String name){
        System.out.println(this.id+this.name+"["+this.nickname+"]" +" say hello to " + name);
    }
}

这时我们传入如下参数

 
        
        
        
    

结果: nullperson1[person2] say hello to at 这时spring调用了Person的public Person(String name, String nickname)方法 。但是,如果我们传入下面的参数:


    
    

结果:null1[person2] say hello to at这个时候还是调用的Person的 Person(String name, String nickname)方法,实际上我们要调用的是public Person(Integer id, String name) 方法,Spring没有办法帮我们调用到。因为Spring调用有参构造方法的逻辑按照构造方法的定义顺序,从上往下找到第一个满足参数个数匹配的方法来调用。

1、基于Setter的注入(重要)

setter注入时Spring中最流行的注入方式,它的原理是先调用无参构造方法,然后调用对应的set方法来为属性赋值。用setter的方式可以解决有参构造方法注入的问题,并且可以提高可读性。

1、改造Person

@Setter //Setter注解自动为属性设置set方法
public class Person {
    private Integer id;
    private String name;
    private String nickName;

    public void sayHello(String name){
        System.out.println(this.id+this.name+"["+this.nickName+"]" +" say hello to " + name);
    }
}

2、用过property设置属性






2、xml装配bean

Spring提供了三种方式来对Bean进行配置

1、在xml文件中配置

2、在Java接口和实现类中配置

3、隐式Bean的发现机制和自动装配原则

分析bean标签

1、bean标签有一个id属性,这个id属性就是为bean取的一个全局唯一的名字。这个属性不是一个必须的属性,,如果没有声明它,那么Spring会采用"全限定名#{number}"的方式自动为我们生成一个编号,number从0开始计数。比如我们声明了两个Person对象,如下:

    
        
        
        
    
    
        
        
        
    

这个时候我们再用原来的方式获取Person就获取不到了,因为我们的id时Spring自动生成的,我们并没有指定。

public class IocTest {
    public static void main(String[] args) {
        ApplicationContext ctx=new ClassPathXmlApplicationContext("spring-ioc-cfg.xml");
        //Person person = (Person)ctx.getBean("com.tgxit.spring.atioc.beans.Person#0");
        Person person = (Person) ctx.getBean(Person.class.getName()+"#0");
        person.sayHello("周杰伦");
    }
}

2、class就是我们要注入的对象类型,这里填写一个类的全限定名

3、property元素定义类的属性,其中name表示属性名,value表示属性值

3、装配集合(重要)

通过property标签的方式实现注入。但是这个对于一些基本数据类型和String类型的数据注入比较方便。如果我们要注入的类型是集合类型(List、Set、Map、Properties)怎么办?

1、接下来我们定义一个新的类:

@Data
public class Coder {
    private String name;
    private List languages;
    private Set friends;
    private Map houses;
    private Properties properties;
}

2、在配置文件中注入Coder:


    
    
            
                java
                c++
                sql
                shell
                javascript
            
    
    
        
            肖战
            王一博
            迪丽热巴
            蔡徐坤
        
    
    
        
            
            
            
        
    
    
        
            180
            140
            18
        
    

3、调用测试:

private static void testCoder(){
    ApplicationContext ctx=new ClassPathXmlApplicationContext("spring-ioc-cfg.xml");
    Coder coder = (Coder) ctx.getBean("coder");
    System.out.println(coder);
}
4、复杂bean装配 (重要)

1、定义三个类

@Data
public class User {
    private Integer id;
    private String name;
}
@Data
public class Role {
    private Integer id;
    private String name;
}
@Data
public class UserRole {
    private Integer id;
    private List users;
    private Map map;
}

2、注入的思路,首先把以来的对象给注入了,然后再来注入自己:

    
        
        
    
    
        
        
    

    
        
        
    
    
        
        
    

    
        
        
            
                
                
            
        
        
            
                
                
            
        
    

3、测试并打印输出结果:

private static void testComplexBean(){
    ApplicationContext ctx=new ClassPathXmlApplicationContext("spring-ioc-cfg.xml");
     UserRole userRole = (UserRole) ctx.getBean("userRole");
    System.out.println(userRole);
}
5、命名空间的装配(了解) Spring注解方式装配Bean

1、概述

通过之前的学习,我们已经知道如何使用XML的方式去装于Bean但是更多的时候我们已经不再推荐使用XAM的方式去装面Bean,更多时候会考虑使用注解的方式去装于Pen。使用注郓的方式可以减少AM的配置,并且注解功能更为强大,它即能实现XM的功能,也提供了自动装配的功能,采用了自动装配后,程序员所需要做的决断就少了,更有利于对程序的开发,这就是约定大于配置的开发原则。

在Spring中,提供了两种方式来发现Bean:

组件扫描:通过定义资源的方式,让Spring loc容器扫描对应的包,从而把Bean装配进来。

自动装配:通过定义注解,让—些依赖关系可以通过注解完成。

2、定义一个类

@Component
@Data
public class Dog {
    @Value("1")
    private Integer id;

    @Value("发发")
    private String name;

    @Value("贵宾犬")
    private  String breed;

}

3、测试

public class TgAnnIocTest01 {
    public static void main(String[] args) {
        //获取Spring上下文
        ApplicationContext ctx=new AnnotationConfigApplicationContext(TgAnnIocConfig.class);
        Dog dog = (Dog) ctx.getBean("dog");
        System.out.println(dog);
    }
}
代码分析:

1、@Component注解代表Spring会把注解修饰的类扫描成bean。这个注解的value属性就相当于我们在XML中配置的bean的id。在不指定value属性时,spring会自动为我们生成一个id,这个id就是我们的类名首字母小写

2、@Value注解代表的是注入的值,这里我们只是简单的注入了一些值。这个地方id是int类型,我们不用操心,Spring会自己知道帮我们转换的。

3、我们定义了一个类TgAnnIocConfig。这个类就相当于我们之前用过的XML配置文件,可以把它理解为Spring的一个配置类。这个类里面我们使用了一个注解@ComponentScan,这个注解代表的就是扫描当前包和子包。

4、使用了注解的方式注入bean在之后,我们开发的时候上下文用AnnotationConfigApplicationContext。

自定义扫描包

按照之前讲的方式,我们定义的扫描配置只能扫描配置类对应的包和子包。但在真正的开发中,我们更多的情况是需要自定义要扫描的包的路径,这个时候如何解决呢?

@Component有一个属性叫basePackages,这个属性是一个数组,这个数组里面存放的就是我们要扫描的包的路径。只要你配置了这个属性,Spring会自动扫描你配置的包和下面的子包。

@ComponentScan(basePackages = "com/tgxit/spring/annioc/beans")

扫描多个包

@ComponentScan(basePackages = {
        "com/tgxit/spring/annioc/beans",
        "com/tgxit/spring/annioc/beans1",
        "com/tgxit/spring/annioc/beans2",
        "com/tgxit/spring/annioc/beans3"
})
自定义扫描类

我们还可以通过指定对应的类的方式来进行扫描,如果我们指定了对应的类,那么Spring会扫描对应的类所在包下面的所有类。

1、定义一个新的类Cat

@Component
@Data
public class Cat {
    @Value("1")
    private Integer id;

    @Value("汤圆")
    private String name;

    @Value("美短")
    private String breed;
}

2、@ComponentScan的属性basePackageClasses扫描Cat类所在包下面的所有类

@ComponentScan(basePackageClasses = Cat.class)
public class TgAnnIocConfig {
}

3、测试

public class TgAnnIocTest01 {
    public static void main(String[] args) {
        ApplicationContext ctx=new AnnotationConfigApplicationContext(TgAnnIocConfig.class);
        Dog dog = (Dog) ctx.getBean("dog");
        System.out.println(dog);
        Cat cat = (Cat) ctx.getBean("cat");
        System.out.println(cat);
    }
}
按类型获取bean

按照之前我们学习的,我们获取类对应的id是通过id来获取的。其实Spring还给我们提供了通过类型来获取bean的方式。

public class TgAnnIocTest01 {
    public static void main(String[] args) {
    	  //获取spring的上下文
          ApplicationContext ctx=new AnnotationConfigApplicationContext(TgAnnIocConfig.class);
		 //在ioc容器中找到对应的类型的bean,然后返回
          Dog dog=ctx.getBean(Dog.class);
          System.out.println(dog);
          Cat cat=ctx.getBean(Cat.class);
          System.out.println(cat);
    }
}
自动装配

我们上面给大家介绍的Dog,Cat这些类的属性,要不是Int,要不是String。反正都是一些简单的数据类型,但是如果有一个类是复杂的数据类型的怎么办?

@Component
@Data
public class Cat {
    @Value("1")
    private Integer id;

    @Value("汤圆")
    private String name;

    @Value("美短")
    private String breed;

    @Autowired
    private Master master;
}

这里我们使用了Autowired注解。这个注解的作用是,Spring把所有的Bean都生成好了后,如果发现了有这个注解,Spring就会按这个属性的类去Spring容器里面找到找到对应的已经创建好的Bean,然后注入到这个属性中。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/361881.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号