【Spring】5.注解注入

28 篇文章 0 订阅


我们使用面向对象编程 , 对象的创建与对象间的依赖关系 完全硬编码在程序中,对象的创建由程序自己控制,控制反转后将对象的创建转移给第三方,个人认为 所谓控制反转就是:获得依赖对象的方式反转了。
控制反转是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式。在Spring中实现 控制反转的是IoC容器,其实现方法是依赖注入(Dependency Injection,DI)。

5.1Bean的自动装配注解

5.1.1@Autowired、@Qualifier、@Resource

  • 自动装配是使用spring满足bean依赖的一种方法
  • spring会在应用上下文中为某个bean寻找其依赖的bean。

Spring中bean有三种装配机制,分别是:

  1. 在xml中显式配置;
  2. 在java中显式配置;
  3. 隐式的bean发现机制和自动装配。
    笔记主要为第三种:自动化的装配bean。

Spring的自动装配需要从两个角度来实现,或者说是两个操作:

  1. 组件扫描(component scanning):spring会自动发现应用上下文中所创建的bean;
  2. 自动装配(autowiring):spring自动满足bean之间的依赖,也就是我们说的IoC/DI;
    组件扫描和自动装配组合发挥巨大威力,使的显示的配置降低到最少。
    推荐不使用自动装配xml配置 , 而使用注解 .

5.1.1.1新建项目

在这里插入图片描述

  • 新建实体类
public class Cat {
    public void shout() {
        System.out.println("miao~");
    }

}

package com.node.pojo;

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

package com.node.pojo;

public class User {
    private Cat cat;
    private Dog dog;

    public Cat getCat() {
        return cat;
    }

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

    public Dog getDog() {
        return dog;
    }

    public void setDog(Dog dog) {
        this.dog = dog;
    }

    @Override
    public String toString() {
        return "User{" +
                "cat=" + cat +
                ", dog=" + dog +
                '}';
    }
}

  • 配置
<bean id="dog" class="com.node.pojo.Dog"/>
<bean id="cat" class="com.node.pojo.Cat"/>

<bean id="user" class="com.node.pojo.User">    
<property name="cat" ref="cat"/>    
<property name="dog" ref="dog"/>

</bean>
  • 测试
public class Mytest {
    @Test
    public void User(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        User user = context.getBean("user", User.class);
        user.getCat().shout();
        user.getDog().shout();
    }
}

5.1.1.2byName

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

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

<bean id="user" class="com.node.pojo.User" autowire="byName">
</bean>

需要看set方法,如果setDog,则id为dog或Dog
如果setDog11,则id为dog11

5.1.1.3byType

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

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


<bean id="user" class="com.node.pojo.User" autowire="byType">
</bean>
  • 测试,报错:NoUniqueBeanDefinitionException
删掉cat2或则删掉cat,也或者将cat的bean名称改掉(把id="cat"删掉)!测试!因为是按类型装配,所以并不会报异常,也不影响最后的结果。甚至将id属性去掉,也不影响结果。找到这个类型即可

5.1.2使用注解

jdk1.5开始支持注解,spring2.5开始全面支持注解。

准备工作: 利用注解的方式注入属性。

  • 在spring配置文件中引入context文件头
xmlns:context="http://www.springframework.org/schema/context" http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
  • 开启属性注解支持!
<context:annotation-config/>

在这里插入图片描述

在这里插入图片描述

5.1.2.1 @Autowired

  • @Autowired是按类型自动转配的,不支持id匹配。
  • 需要导入 spring-aop的包!

5.1.2.2测试

  • 将User类中的set方法去掉,使用@Autowired注解
package com.node.pojo;

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

import javax.annotation.Resource;

public class User {
    @Autowired
    @Autowired(required = false)// 说明: false,对象可以为null;true,对象必须存对象,不能为null。默认为true
   
    private Cat cat;
    @Autowired
    private Dog dog;

    public Cat getCat() {
        return cat;
    }


    public Dog getDog() {
        return dog;
    }


    @Override
    public String toString() {
        return "User{" +
                "cat=" + cat +
                ", dog=" + dog +
                '}';
    }
}

  • 配置文件
<context:annotation-config/>
<bean id="dog" class="com.kuang.pojo.Dog"/>
<bean id="cat" class="com.kuang.pojo.Cat"/>
<>

5.1.2.3@Qualifier

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

5.1.2.4测试

  • 配置文件修改内容,保证类型存在对象。且名字不为类的默认名字!
<bean id="dog1" class="com.kuang.pojo.Dog"/>
<bean id="dog2" class="com.kuang.pojo.Dog"/>
<bean id="cat1" class="com.kuang.pojo.Cat"/>
<bean id="cat2" class="com.kuang.pojo.Cat"/>
  • 这样运行没有加@Qualifie注解就会报错,则
@Autowired 
@Qualifier(value = "cat2") 
private Cat cat; 
@Autowired @Qualifier(value = "dog2") 
private Dog dog;

5.1.2.5@Resource

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

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

import javax.annotation.Resource;

public class User {
    @Resource
    private Cat cat;
    @Resource
    private Dog dog;

    public Cat getCat() {
        return cat;
    }


    public Dog getDog() {
        return dog;
    }


    @Override
    public String toString() {
        return "User{" +
                "cat=" + cat +
                ", dog=" + dog +
                '}';
    }
}

5.1.3小结

@Autowired与@Resource异同:

  • @Autowired与@Resource都可以用来装配bean。都可以写在字段上,或写在setter方法上。
  • @Autowired默认按类型装配(属于spring规范),默认情况下必须要求依赖对象必须存在,如果 要允许null 值,可以设置它的required属性为false,如:@Autowired(required=false) ,如果我 们想使用名称装配可以结合@Qualifier注解进行使用
  • @Resource(属于J2EE复返),默认按照名称进行装配,名称可以通过name属性进行指定。如果 没有指定name属性,当注解写在字段上时,默认取字段名进行按照名称查找,如果注解写在 setter方法上默认取属性名进行装配。 当找不到与名称匹配的bean时才按照类型进行装配。但是 需要注意的是,如果name属性一旦指定,就只会按照名称进行装配。
  • 它们的作用相同都是用注解方式注入对象,但执行顺序不同。@Autowired先byType,@Resource先 byName。
    在这里插入图片描述

5.2 Bean的属性注入

5.2.1@Component、@Value

  • User.java
@Component// 组件  相当于配置文件中 <bean id="user" class="当前注解的类"/>
@Scope("singleton")  //作用域:单例模式(singleton) 多例模式(prototype)
public class User {
    @Value("mmm~")
    public String Cat;
    @Value("www~")
    public String dog;
}

在这里插入图片描述

  • applicationContext.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"
       xmlns:aop="http://www.springframework.org/schema/aop"
       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
           http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd"
>

    <context:component-scan base-package="com.node.pojo"/>
    <context:annotation-config/>

</beans>

在这里插入图片描述

  • Mytest.java
public class Mytest {
    @Test
    public void User(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        User user = context.getBean("user", User.class);
        System.out.println(user.Cat);
        System.out.println(user.dog);
    }
}

5.3 Bean的衍生注解

5.3.1@Controller、@Service、@Repository

我们这些注解,就是替代了在配置文件当中配置步骤而已
!更加的方便快捷!
@Component三个衍生注解
为了更好的进行分层,Spring可以使用其它三个注解,功能一样,目前使用哪一个功能都一样。

  • @Controller:web层 连接层
  • @Service:service层 业务层
  • @Repository:dao层 接口 写上这些注解,就相当于将这个类交给Spring管理装配了!

在这里插入图片描述

  • UserController.java
@Controller
public class UserController {
    @Value("111")
    public String a;
}
  • UserDao
@Repository
public class UserDao {
    @Value("222")
    public String b;
}
  • UserService
@Service
public class UserService {
    @Value("333")
    public String c;
}
  • applicationContext.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"       
xmlns:aop="http://www.springframework.org/schema/aop"       
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          
http://www.springframework.org/schema/aop        
https://www.springframework.org/schema/aop/spring-aop.xsd">   
 <context:component-scan base-package="com.node"/>   
  <context:annotation-config/></beans>
  • Mytest.java
public class Mytest {
    @Test
    public void User(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserDao userDao = context.getBean("userDao", UserDao.class);
        System.out.println(userDao.b);
    }
}

5.4 基于Java类(显式)的进行配置(全注解)

5.4.1 @Configuration

JavaConfig 原来是 Spring 的一个子项目,它通过 Java 类的方式提供 Bean 的定义信息,在 Spring4 的 版本, JavaConfig 已正式成为 Spring4 的核心功能 。
在这里插入图片描述

  • Myconfig.java
@Configuration
public class Myconfig {
    @Bean//把当前方法的返回值作为bean对象存入spring的ioc容器中
    public Dog dog(){
        return new Dog();
    }
}
  • Dog.java
@Component
public class Dog {
    public String name = "dog";
}
  • Mytest.java
public class Mytest {
    @Test
    public void mytest(){
        ApplicationContext applicationContext=new
                AnnotationConfigApplicationContext(Myconfig.class);
        Dog dog=applicationContext.getBean("dog",Dog.class);
        System.out.println(dog.name);}

}

5.4.2 导入其他配置

  • Myconfig2.java
@Configuration //代表这是一个配置类 
public class MyConfig2 { 

}
  • 在之前的配置类中我们来选择导入这个配置类
@Configuration 
@Import(MyConfig2.class) //导入合并其他配置类,类似于配置文件中的 inculde 标签 

public class MyConfig {
    @Bean 
    public Dog dog(){ 
    return new Dog(); 
    } 
}

关于这种Java类的配置方式,我们在之后的SpringBoot 和 SpringCloud中还会大量看到,我们需要知道 这些注解的作用即可!

5.5总结

5.5.1XML与注解比较

  • XML可以适用任何场景 ,结构清晰,维护方便
  • 注解不是自己提供的类使用不了,开发简单方便

5.5.2xml与注解整合开发 :推荐最佳实践

  • xml管理Bean
  • 注解完成属性注入
  • 使用过程中, 可以不用扫描,扫描是为了类上的注解
<context:annotation-config/>

作用:

  • 进行注解驱动注册,从而使注解生效
  • 用于激活那些已经在spring容器里注册过的bean上面的注解,也就是显示的向Spring注册
  • 如果不扫描包,就需要手动配置bean
  • 如果不加注解驱动,则注入的值为null!

6.模拟整合

/**
 * Spring练习
 * 1、新建一个Admin类
 * 有loginName、passWord 这两个属性
 * 2、新建LoginDao
 * 有getAdmin()方法,返回一个注入进来的Admin对象
 * 3、新建loginService
 * 有isLogin(String loginName,int password)
 * 从dao获取管理员信息,对比用户名密码是否正确
 * 返回登入成功或失败
 * 4、新建LoginController
 * 有toLogin(String lname,int pwd)方法
 * 返回登入状态
 * 测试类
 * 加载Spring配置文件,实现输入登入名与密码输出登录状态
 */

6.1 Pom

<dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.2.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.16</version>
        </dependency>

6.2 LoginDao

package com.node.dao;

import com.node.pojo.Admin;

public class LoginDao {

    private Admin admin;

    public void setAdmin(Admin admin) {  //通过Set注入
        this.admin = admin;
    }

    public   Admin getAdmin(){
        System.out.println(admin);
        return admin;
    }
}

6.3 LoginService

package com.node.service;

import com.node.dao.LoginDao;
import com.node.pojo.Admin;

public class LoginService  {

    private LoginDao loginDao;

    public void setLoginDao(LoginDao loginDao) {  //通过set注入
        this.loginDao = loginDao;
    }

    public boolean isLogin(String loginName, int password){
      Admin admin= loginDao.getAdmin();
      if (admin.getLoginName()!=loginName&&admin.getPassword()!=password){
          return false;
      }else
          return true;

    }
}

6.4 LoginController

package com.node.controller;

import com.node.service.LoginService;
import org.springframework.beans.factory.annotation.Autowired;

public class LoginController {
	@Autowired
    LoginService service;  //通过注解注入 需在xml文件导入头文件并开启注解
    
    public boolean toLogin(String lname, int pwd){
        boolean i=service.isLogin(lname,pwd);
        if (i){
            return true;
        }else
            return false;
    }
}

6.5 Test

package com.node;

import com.node.controller.LoginController;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.Scanner;

public class Test {
    public static void main(String[] args) {
        ApplicationContext context1 = new ClassPathXmlApplicationContext("beans.xml");
        LoginController loginController = (LoginController) context1.getBean("LoginController");
        Scanner s=new Scanner(System.in);
        String name=s.next();
        int pa=s.nextInt();
        boolean i=  loginController.toLogin(name,pa);
        System.out.println(i);
    }
}

6.6 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.xsd
                            http://www.springframework.org/schema/context
                            http://www.springframework.org/schema/context/spring-context.xsd
"
       xmlns:context="http://www.springframework.org/schema/context"
>
//开启注解
<context:annotation-config/>

    <bean id="Admin" class="com.node.pojo.Admin">
        <property name="loginName" value="123"></property>
        <property name="password" value="123456"></property>
    </bean>

    <bean id="LoginDao" class="com.node.dao.LoginDao">
        <property name="admin" ref="Admin"></property>
    </bean>

    <bean id="LoginService" class="com.node.service.LoginService">
        <property name="loginDao" ref="LoginDao"></property>
    </bean>


    <bean id="LoginController" class="com.node.controller.LoginController"></bean>


</beans>

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值