Spring之ioc注解

基于注解实现ioc注解

对于 DI 使用注解,将不再需要在 Spring 配置文件中声明 bean 实例。 Spring 中使用注解,需要在原有 Spring 运行环境基础上再做一些改变。
作用:使用注解替代配置文件,方便管理
缺点:源代码加入大量注解会有些凌乱

1.声明Bean的注解 @Component

在类上添加注解 @Component 表示该类创建对象的权限交给 Spring 容器。注解的 value 属性用于指定 bean的 id 值, value 可以省略。
@Component 不指定 value 属性, bean id 是类名的首字母小写

2.包扫描

第一步:修改文件头 

<?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:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    <!--开启注解扫描-->
    <!--要扫描多个包之间可以使用空格,“,”,“;”分割
    <context:component-scan base-package="com.kkb.spring.po;com.kkb.spring.dao;com.kkb.spring.service;com.kkb.spring.controller"></context:component-scan>
    -->
    <!--指定父包的形式来扫描多个包-->
    <context:component-scan base-package="com.lr.spring."></context:component-scan>
</beans>

使用多个context:component-scan指定不同的包路径

多个包扫描,可以用空格或者逗号或者分号进行隔离,三种方式都可以用,不建议使用直接扫描父包的形式来扫描多个包。极限开发原则,因为会消耗性能。

第二步:加入注解

在User中加入注解@Component的作用相当于加入这样的标签

import org.springframework.stereotype.Component;

import java.io.Serializable;
//在类上添加注解@Component表示该类创建对象的权限交给Spring容器。注解的value属性用于指定bean的id值,value可以省略。
//@Component 不指定 value 属性,bean 的 id 是类名的首字母小写
@Component
//<bean id="user" class="com.kkb.spring.po.User">
public class User implements Serializable {
    public Integer id;
    private String name;
    private String password;

 第三步:测试效果

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

 修改注解

@Component(value = "user1")

 运行程序报错

 没有找到user类型

说明参数对应的值是注解的value值

3.其他注解

除@Component 之外,Spring 中还提供了其他 3 个用于创建对象的注解:
@Repository : 用于 dao 实现类的的注解
@Service: 用户 service 实现类的注解
@Controller: 用于 controller 实现类的注解
这三个注解与 @Component 都可以创建对象,但这三个注解还有其他的含义, @Service 创建业务层对 象,业务层对象可以加入事务功能,@Controller 注解创建的对象可以作为处理器接收用户的请求。
@Repository @Service @Controller 是对 @Component 注解的细化,标注不同层的对象。即持久层对象,业务层对象,控制层对象。
在各类添加不同的注解
package com.lr.spring.dao;

import org.springframework.stereotype.Repository;

@Repository
public class UserDaoImpl implements UserDao {
    @Override
    public void addUser() {
        System.out.println("Dao中输入User对象");
    }
}


package com.lr.spring.dao;

import org.springframework.stereotype.Repository;

@Repository
public class UserMySQLDaoImpl implements UserDao {
    @Override
    public void addUser() {
        System.out.println("MySQLDa");
    }
}

package com.lr.spring.dao;

import org.springframework.stereotype.Repository;

@Repository
public class UserOracleDaoImpl implements UserDao {
    @Override
    public void addUser() {
        System.out.println("OracleDao");
    }
}


package com.lr.spring.controller;

import org.springframework.stereotype.Controller;

@Controller
public class UserController {
}


package com.lr.spring.service;

import org.springframework.stereotype.Service;
//接口上不起作用
@Service
public interface UserService {
    void addUser();
}

测试

    @Test
    public void test05(){
        ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        UserController userController = (UserController) context.getBean("userController");
        System.out.println(userController);
        UserMySQLDaoImpl userMySQLDao = (UserMySQLDaoImpl) context.getBean("userMySQLDaoImpl");
        System.out.println(userMySQLDaoImpl);

    }

测试service类

   UserService userService=(UserService) context.getBean("userService");
        System.out.println(userService);

 报错没有bean的名字是UserService

这些注解本质上跟@Component一样,只能在类上修饰而UserService是一个接口,我们要把注解@Service放到实现类中,在重新给它一个value值userService就可以了

mport com.lr.spring.dao.UserDao;
import com.lr.spring.dao.UserDaoImpl;
import org.springframework.stereotype.Service;

@Service("userService")
public class UserServiceImpl implements UserService {
//    private UserDaoImpl userDao = new UserDaoImpl();
    private UserDao userDao;

    //set注入
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

 ps:@Component("user1")等价于@Component(value = "user1")

只有一个值,value可以省略

4.属性注入@Vaule

需要在属性上使用注解 @Value ,该注解的 value 属性用于指定要注入的值。使用该注解完成属性注入时,类中无需 setter 。当然,若属性有 setter ,则也可将其加到 setter 上。
package com.lr.spring.po;

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

import java.io.Serializable;
//在类上添加注解@Component表示该类创建对象的权限交给Spring容器。注解的value属性用于指定bean的id值,value可以省略。
//@Component 不指定 value 属性,bean 的 id 是类名的首字母小写
@Component(value = "user1")
//<bean id="user1" class="com.kkb.spring.po.User">
public class User implements Serializable {
    @Value("1000")
    public Integer id;
    @Value("龙仁")
    private String name;
    @Value("1380341")
    private String password;

 测试效果

@Test
    public void test05(){
        ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        User user = (User) context.getBean("user1");
        System.out.println(user);
    }

}

 

4 @Autowired和@Qualifier

      ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        User user = (User) context.getBean("user1");
        System.out.println(user);
        UserService userService=(UserService) context.getBean("userService");
        System.out.println(userService);
                //空指针异常
        userService.addUser();

 

我们可以拿到这个 userService对象,但是调用add方法后,发生空指针异常,原因是程序走到这的时候,接口还是无法识别注解

我们需要在UserServiceImpl的逻辑处加入@Autowired  自动装配   这个注解

@Service("userService")
public class UserServiceImpl implements UserService {
//    private UserDaoImpl userDao = new UserDaoImpl();
    //自动装配
    @Autowired
    private UserDao userDao;

 但是此时注意@Autowired的默认属性是byType 类型匹配 

程序依旧会报错因为我们有三个bean(三个实现类),他不知道该找哪个?

@Autowired
    @Qualifier("userMySQLDaoImpl")
    private UserDao userDao;

组合注解 相当于把 byType改成byName

 

byType 自动注入 @Autowired

 需要在引用属性上使用注解@Autowired,该注解默认使用按类型自动装配 Bean 的方式。使用该注解完成属性注入时,类中无需 setter。当然,若属性有 setter,则也可将其加到 setter 上。

byName 自动注入 @Autowired @Qualifier
需要在引用属性上联合使用注解 @Autowired @Qualifier @Qualifier value 属性用于指定要匹配
Bean id 值。类中无需 set 方法,也可加到 set 方法上。
@Autowired 还有一个属性 required ,默认值为 true ,表示当匹配失败后,会终止程序运行。若将其值
设置为 false ,则匹配失败,将被忽略,未匹配的属性值为 null

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值