Spring学习(三)--- Spring的常用注解

        学习基于注解的IoC配置,首先得有一个认知,即注解配置和xml 配置要实现的功能都是一样的,都是要降低程序间的耦合。只是配置的形式不一样。

 曾经基于XML的配置,此处用作参考:
   <bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl"
         scope=""  init-method=""  destroy-method=""  >
       <property name=""  value=""  ref="" ></property>
   </bean>

1 用于创建对象的
       他们的作用就和在XML配置文件中编写一个<bean>标签实现的功能是一样的
       @Component
           作用:用于把当前类对象存入spring容器中
           属性
               value:用于指定bean的id。当我们不写时,它的默认值是当前类名,且首字母改小写。
       @Controller: 一般用在表现层
       @Service:     一般用在业务层
       @Repository:一般用在持久层
       以上三个注解他们的作用和属性与Component是一模一样。
       他们三个是spring框架为我们提供明确的三层使用的注解,使我们的三层对象更加清晰

注意:关于注解的细节:
        如果一个注解中有一个value属性,那这个value属性的名称是可以不写的。注意:只能是给一个属性赋值,且属性名是value时;如果同时有两个属性,这个时候value也必须得写。
如下面两图:

Client.java

    public static void main(String[] args) {
        //1.获取核心容器对象
        ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
        //2.根据id获取Bean对象
        IAccountService as  = (IAccountService)ac.getBean("accountService");
        System.out.println(as);
        IAccountDao adao = ac.getBean("accountDao",IAccountDao.class);
        System.out.println(adao);
    }

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

    <!--告知spring在创建容器时要扫描的包,配置所需要的标签不是在beans的约束中,而是一个名称为
    context名称空间和约束中-->
    <!--add by szj
        加上com.itheima包之后,这个时候,Spring就会扫描com.itheima包下及其子包下所有类上及接口上的注解
    -->
    <context:component-scan base-package="com.itheima"></context:component-scan>
</beans>

AccountServiceImpl.java

/**
 * 账户的业务层实现类
 */
@Component("accountService")
public class AccountServiceImpl implements IAccountService {
    private IAccountDao accountDao;

    public AccountServiceImpl(){
        System.out.println("对象创建了");
    }

    public void  saveAccount(){
        accountDao.saveAccount();
    }
}

AccountDaoImpl.java

/**
 * 账户的持久层实现类
 */
@Repository("accountDao")
public class AccountDaoImpl implements IAccountDao {

    public  void saveAccount(){

        System.out.println("保存了账户");
    }
}

-------------------------------------------------------------------------------------------------------------------------------------------

2 用于注入数据的
       他们的作用就和在xml配置文件中的bean标签中写一个<property>标签的作用是一样的
       @Autowired:
           作用:自动按照类型注入。只要容器中有唯一的一个bean对象类型和要注入的变量类型匹配,就可以注入成功
                 如果ioc容器中没有任何bean的类型和要注入的变量类型匹配,则报错。
                 如果Ioc容器中有多个类型匹配时:(见下面解析)

           出现位置
                可以是变量上,也可以是方法上
            细节
                在使用注解注入时,set方法就不是必须的了。

        如果有唯一的一个匹配时,直接注入;如果Ioc容器中有多个类型匹配时,则:
        如果有多个匹配时,首先它先按照类型圈定出来匹配的对象(图片中红线部分,匹配的是两个);然后,它会使用 变量名称作为bean的id,在圈定出来的2个中继续查找(图中蓝色线部分),看看那个与其一样:如果有一样的,它也可以注入成功;如果两个都不一样,则会报错。

 

例如:首先依据红线部分,按照类型,有两个IAccountDao,然后根据变量名称作为bean的id继续查找。

AccountServiceImplement.java

@Service("accountService")
public class AccountServiceImpl implements IAccountService {

    @Autowired
    private IAccountDao accountDao1 = null;   //或者private IAccountDao accountDao2 = null;

    public void  saveAccount(){
        accountDao1.saveAccount();  //或者accountDao2.saveAccount();
    }
}

AccountDaoImpl1.java

/**
 * 账户的持久层实现类
 */
@Repository("accountDao1")
public class AccountDaoImpl implements IAccountDao {

    public  void saveAccount(){
        System.out.println("保存了账户1111111111111");
    }
}

AccountDaoImpl2.java

/**
 * 账户的持久层实现类
 */
@Repository("accountDao2")
public class AccountDaoImpl2  implements IAccountDao {

    public  void saveAccount(){
        System.out.println("保存了账户2222222222222");
    }
}

        @Qualifier:
           作用:在按照类中注入的基础之上再按照名称注入。它在给类成员注入时不能单独使用。但是在给方法参数注入时可以。
           属性
               value:用于指定注入bean的id。

示例:

        此处,想把accountDao1注进来就写accountDao1,想把accountDao2注进来就写accountDao2,但是,@Qualifier不能单独使用,必须配合@Autowired一起使用。

    @Autowired
    @Qualifier("accountDao1")
    private IAccountDao accountDao = null;


      @Resource
           作用:直接按照bean的id注入。它可以独立使用
           属性
               name:用于指定bean的id。(它的属性不再是value)

@Service("accountService")
public class AccountServiceImpl implements IAccountService {

    @Resource(name = "accountDao2")
    private IAccountDao accountDao = null;

    public void  saveAccount(){
        accountDao.saveAccount();
    }
}

个人理解:

(1)这个地方,位置1,accountDao1,accountDao2,accountService都是第一步已经创建的对象并且已经注入到Spring容器中的,如果没有注入容器中,此处不能选。

(2)位置2必须是根据位置1作为id,所能找到的bean的数据类型,如果不一致,会报错。

(3)位置3,个人感觉就相当于是起了一个别名,或者说是“你在你自己的地方叫accountDao2,我现在需要这个bean,所以我注入到我自己的里面,所以,我让它在我这里叫accountDao。”

PS:或者理解成,位置1是把需要的bean注入进来后,位置2、3就是定义变量额过程(因为我里面已经有了这个bean,所以可以任意定义)。

 

       以上三个注入都只能注入其他bean类型的数据,而基本类型和String类型无法使用上述注解实现。
       另外,集合类型的注入只能通过XML来实现。
 
       @Value:
           作用用于注入基本类型和String类型的数据
           属性
               value:用于指定数据的值。它可以使用spring中SpEL(也就是spring的el表达式)
                       SpEL的写法:${表达式}

-------------------------------------------------------------------------------------------------------------------------------------------

3 用于改变作用范围的

      他们的作用就和在bean标签中使用scope属性实现的功能是一样的
      @Scope
          作用:用于指定bean的作用范围
         属性:
             value:指定范围的取值。常用取值:singleton   prototype

示例代码:

Client.java


  public static void main(String[] args) {
        //1.获取核心容器对象
        ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");    
        //2.根据id获取Bean对象
        IAccountService as  = (IAccountService)ac.getBean("accountService");
        IAccountService as2  = (IAccountService)ac.getBean("accountService");
        System.out.println(as == as2);
        as.saveAccount();
    }

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

    <!--告知spring在创建容器时要扫描的包,配置所需要的标签不是在beans的约束中,而是一个名称为
    context名称空间和约束中-->
    <!--add by szj
        加上com.itheima包之后,这个时候,Spring就会扫描com.itheima包下及其子包下所有类上及接口上的注解
    -->
    <context:component-scan base-package="com.itheima"></context:component-scan>
</beans>

AccountServiceImpl.java


/**
 * 账户的业务层实现类
 * 加上 @Scope("prototype") 后,就变成了多例对象
 */
@Service("accountService")
@Scope("prototype")
public class AccountServiceImpl implements IAccountService {

    @Resource(name = "accountDao2")
    private IAccountDao accountDao = null;

    public void  saveAccount(){
        accountDao.saveAccount();
    }
}

AccountDaoImpl.java

/**
 * 账户的持久层实现类
 */
@Repository("accountDao")
public class AccountDaoImpl implements IAccountDao {
    public  void saveAccount(){
        System.out.println("保存了账户");
    }
}

 输出结果:

加上 @Scope("prototype") :变成多例对象,输出结果为false

不加@Scope 或者 加上@Scope("singleton")   为单例对象,输出结果为true

-------------------------------------------------------------------------------------------------------------------------------------------

 4 和生命周期相关   ---了解---
      他们的作用就和在bean标签中使用init-method和destroy-methode的作用是一样的
      @PreDestroy
          作用:用于指定销毁方法
      @PostConstruct
          作用:用于指定初始化方法

示例代码:

Client.java

public static void main(String[] args) {
        //1.获取核心容器对象
        //ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
        //此处只能用子类,不能用父类。
        ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
        //2.根据id获取Bean对象
        IAccountService as  = (IAccountService)ac.getBean("accountService");

        as.saveAccount();
        ac.close();
    }

bean.xml   同上

AccountServiceImpl.java

/**
 * 账户的业务层实现类
 */
@Service("accountService")
public class AccountServiceImpl implements IAccountService {
    @Resource(name = "accountDao2")
    private IAccountDao accountDao = null;

    @PostConstruct
    public void  init(){
        System.out.println("初始化方法执行了");
    }

    @PreDestroy
    public void  destroy(){
        System.out.println("销毁方法执行了");
    }

    public void  saveAccount(){
        accountDao.saveAccount();
    }
}

AccountDaoImpl.java  同上

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值