1.Spring  IOC注解的介绍使用2

  

 需要导入IOC容器需要的6个jar包+spring-aop.jar

1.2 创建包结构并编写Java类

    

UserService接口

package cn.itcast.service;

 

public interface UserService {

  

   /**

    * 业务层:用户保存

    */

   public void save();

  

}

n  UserServiceImpl实现类

package cn.itcast.service.impl;

 

import cn.itcast.service.UserService;

 

public class UserServiceImpl implements UserService{

 

   @Override

   public void save() {

      System.out.println("业务层:用户保存");

   }

 

}

1.3 在java类上添加注解

 在UserServiceImpl实现类上添加注解@Component,相当于<bean id=”” class=””>,value属性给bean指定id,value属性的名字也可以不写,直接写一个值

@Component("userService")

public class UserServiceImpl implements UserService{

 

   @Override

   public void save() {

      System.out.println("业务层:用户保存");

   }

 

}

1.4、在applicationContext.xml中引入约束

        在src目录下,创建applicationContext.xml的配置文件,引入约束。注意:因为现在想使用注解,那么引入的约束发生了变化,需要context的约束

     【提示】:约束可以从spring开发文档中拷贝(如下面红色矩形圈出)

<?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">

     

</beans>

1.5在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"

    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">

      <!-- 开启注解扫描 -->

      <context:component-scan base-package="cn.itcast.service"></context:component-scan>

</beans>

 

1.6、编写测试代码

/**

    * 测试注解

*/

@Test

public void test1(){

      ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");

      UserService userService = (UserService) applicationContext.getBean("userService");

      userService.save();

}

 

 

2、Spring框架中bean管理的常用注解

2.1 用于创建对象的注解(重点)

@Component注解   作用表示把资源让给Spring进行管理,相当于在xml中配置一个bean

                                属性:value:指定bean的id,如果不指定value属性,默认bean的id是当前类的类名,首字母小写

@Controller  @Service @Repository     作用 介绍:这三个注解都是针对于一个的衍生注解,其中他们的作用和属性是一样的,只是提供了更加明确的语义化

@Controller:一般是用于表现层的注解

@Service:一般是用于业务层的注解

@Repository:一般是用于持久层的注解

例如:

//@Component("userService")

@Service("userService")

public class UserServiceImpl implements UserService{

 

   @Override

   public void save() {

      System.out.println("业务层:用户保存");

   }

 

}

 

@Repository("userDao")

public class UserDaoImpl implements UserDao {

 

   @Override

   public void save() {

      System.out.println("持久层:用户保存");

   }

 

}

 

说明总结:这三个注解是为了让标注类本身的用途更加清晰

 

用于注入数据的

相当于:<property name="" ref="">      

                 <property name="" value="">

 

@value:作用注入基本数据类型和String数据类型    value:用于指定值

@Service("userService")

public class UserServiceImpl implements UserService{

  

   @Value("张三")

   private String name;

 

 

   @Override

   public void save() {

      System.out.println("业务层:用户保存");

      System.out.println("用户名:" + name);

   }

 

}

 

@Autowired  作用:

自动按照类型注入。当使用注解注入属性时,set方法可以省略。它只能注入其他bean类型。当有多个类型匹配时,使用要注入的对象变量名称作为bean的id,在spring容器查找,找到了也可以注入成功。找不到就报错。

@Service("userService")

public class UserServiceImpl implements UserService{

  

   @Value("张三")

   private String name;

  

   @Autowired

   private UserDao userDao;

 

 

   @Override

   public void save() {

      System.out.println("业务层:用户保存");

      System.out.println("用户名:" + name);

      userDao.save();

   }

 

}

 

@Qualifer   

作用:

    在自动按照类型注入的基础之上,再按照Bean的id注入。它在给字段注入时不能独立使用,必须和@Autowire一起使用;但是给方法参数注入时,可以独立使用。

属性:

    value:指定bean的id。

 

n  创建UserDao接口的第二个实现类UserDaoImpl2

@Repository("userDao2")

public class UserDaoImpl2 implements UserDao {

 

   @Override

   public void save() {

      System.out.println("持久层2:保存用户");

   }

 

}

n  测试发现,UserServiceImpl中注入的还是第一个UserDaoImpl,想指定注入UserDaoImpl2,需要使用@Qualifier注解根据名字来注入

@Service("userService")

public class UserServiceImpl implements UserService{

  

   @Value("张三")

   private String name;

  

   @Autowired

   @Qualifier("userDao2")

   private UserDao userDao;

 

 

   @Override

   public void save() {

      System.out.println("业务层:用户保存");

      System.out.println("用户名:" + name);

      userDao.save();

   }

 

}

 .@Resource(了解)

作用:

    直接按照Bean的id注入。它也只能注入其他bean类型。

属性:

    name:指定bean的id。

 

@Service("userService")

public class UserServiceImpl implements UserService{

  

   @Value("张三")

   private String name;

  

// @Autowired

// @Qualifier("userDao2")

   @Resource(name="userDao2")

   private UserDao userDao;

 

 

   @Override

   public void save() {

      System.out.println("业务层:用户保存");

      System.out.println("用户名:" + name);

      userDao.save();

   }

 

}

 

 

@Scope:用于改变作用域范围的

作用:

    指定bean的作用范围。

属性:

    value:指定范围的值。

           取值:singleton  prototype request session globalsession

 

n  @Scope指定bean的作用域,默认值是singleton,单例的。

@Service("userService")

@Scope("prototype")

public class UserServiceImpl implements UserService{

  

   @Value("张三")

   private String name;

  

// @Autowired

// @Qualifier("userDao2")

   @Resource(name="userDao2")

   private UserDao userDao;

 

 

   @Override

   public void save() {

      System.out.println("业务层:用户保存");

      System.out.println("用户名:" + name);

      userDao.save();

   }

 

}

n  测试发现:当scope指定为prototype时,两次获取UserService的对象是不一致的

/**

    * 测试注解

    */

@Test

public void test1(){

      ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");

      UserService userService = (UserService) applicationContext.getBean("userService");

      userService.save();

      System.out.println(userService);

     

      UserService userService1 = (UserService) applicationContext.getBean("userService");

      System.out.println(userService1);

   }

Scope还可以取request,session,globalsession;

 

和生命周期相关的(了解)

相当于:<bean id="" class="" init-method="" destroy-method="" />.@PostConstruct注解

@PostConstruct加在方法上,指定bean对象创建好之后,调用该方法初始化对象,类似于xml的init-method方法

@Service("userService")

@Scope("prototype")

public class UserServiceImpl implements UserService{

  

   @Value("张三")

   private String name;

  

// @Autowired

// @Qualifier("userDao2")

   @Resource(name="userDao2")

   private UserDao userDao;

  

   @PostConstruct

   public void init(){

      System.out.println("调用了init方法");

   }

 

 

   @Override

   public void save() {

      System.out.println("业务层:用户保存");

      System.out.println("用户名:" + name);

      userDao.save();

   }

 

}

1.1.2.@PreDestory注解

@PreDestory加在方法上,指定bean销毁之前,调用该方法,类似于xml的destory-method方法

@Service("userService")

@Scope("singleton")

public class UserServiceImpl implements UserService{

  

   @Value("张三")

   private String name;

  

// @Autowired

// @Qualifier("userDao2")

   @Resource(name="userDao2")

   private UserDao userDao;

  

   @PostConstruct

   public void init(){

      System.out.println("调用了init方法");

   }

  

   @PreDestroy

   public void destory(){

      System.out.println("调用了destory方法");

   }

 

 

   @Override

   public void save() {

      System.out.println("业务层:用户保存");

      System.out.println("用户名:" + name);

      userDao.save();

   }

 

}

注意:要看到@PreDestory的效果,需要调用ClassPathXmlApplicationContext.close方法,同时scope的值要是singleton

 

总结:xml和注解的比较

注解的优势:

    配置简单,维护方便。(我们找到了类,就相当于找到了配置)

XML的优势:

    修改时,不用改源码。不涉及重新编译和部署。