• Spring总结四:IOC和DI 注解方式


    首先我们要了解注解和xml配置的区别:

      作用一样,但是注解写在Bean的上方来代替我们之前在xml文件中所做的bean配置,也就是说我们使用了注解的方式,就不用再xml里面进行配置了,相对来说注解方式更为简便。

    IOC获取对象注解方式:

    在我们第二篇(IOC容器配置 xml方式)总结的基础上做修改:

    首先我们的applicationContext.xml配置文件要略作修改:(把beans里面加上绿色背景的配置)

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:context="http://www.springframework.org/schema/context"
           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
    ">
    
        <!--开启扫描 扫描包com.zy下面的-->
        <context:component-scan base-package="com.zy"></context:component-scan>
    </beans>

    然后我们的JavaBean类加上注解(Component):

    @Component("bean1")
    public class Bean1 {
        public Bean1() {
            System.out.println("Bean1的无参构造方法");
        }
    }

    这样就代替了我们之前在applicationContext.xml中配置的: <bean id="bean1" class="com.zy.IoC.Bean1"></bean>

    测试及运行结果请参照总结第二篇,得出的结果是一样的。

    Spring 容器还提供@Component 等效三个衍生注解

    • @Repository 用于注册DAO(持久层 )

    • @Service 用于注册 Service(业务层)

    • @Controller 用于注册 Action (表现层)

    以@Repository为例:

    /**
     * 测试UserDao接口
     */
    public interface UserDao {
        public void getUser();
    }
    /**
     * UserDao实现类1
     */
    @Repository("userDao")
    public class UserDaoImpl implements UserDao {
        public UserDaoImpl() {
            System.out.println("dao1 构造方法");
        }
    
        @Override
        public void getUser() {
            System.out.println("UserDao实现类1  获取用户信息...");
        }
    }

    测试:

        @Test
        public void getUser() throws Exception {
            //根据spring配置文件 获取spring容器
            ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
            //使用容器创建UserDao的实现类对象  userDao和配置文件中的 bean的id一致
            UserDao dao = ac.getBean("userDao", UserDao.class);
            dao.getUser();
        }

    运行结果:

     DI依赖注入注解方式:

    注解基本类型属性:这个不多做介绍了

    // 基本类型属性
    @Value("#{'张学友'}")
    private String name;

    注解复杂类型属性:

      1,Spring3.0提供@Value注解

        // 复杂类型属性
        // 第一种 @Value 结合 spEL
        @Value("#{userDao}")
        private UserDao userDao;

      2,Spring2.0 提供@Autowired 注解 结合 @Qualifier 注解

        // 第二种 @Autowired 注解 结合 @Qualifier 注解
        // 如果单独使用@Autowired 默认按照类型注入,如果有多个同一类型的只能找到一个
        // 使用 @Qualifier 按照名称注入
        @Autowired
        @Qualifier("userDao")
        private UserDao userDao;

      3,JSR-250规范 提供 @Resource 注解实现注入(不推荐使用)

        // 第三种 JSR-250提供@Resource 注解
        // 不写name属性,按照类型注入,写了name属性,按照名称注入
        @Resource(name = "userDao")
        private UserDao userDao;

    以把UserDao注入到UserService为例:

    JavaBean代码:

    /**
     * 测试UserDao接口
     */
    public interface UserDao {
        public void getUser();
    }
    /**
     * UserDao实现类1
     */
    @Repository("userDao")
    public class UserDaoImpl implements UserDao {
        @Override
        public void getUser() {
            System.out.println("2 UserDao实现类1  获取用户信息...");
        }
    }
    
    /**
     * UserService接口
     */
    public interface UserService {
        public void getUser();
    }
    /**
     * UserService实现类
     */
    @Service("userService")
    public class UserServiceImpl implements UserService {
        //@Autowired+@Qualifier的方式
        //@Autowired
        //@Qualifier("userDao")
        
        @value("#{userDao}")  //@Value("#{}")的方式     使用注解注入,要与dao实现类的注解一致(使用注解 不需要setter方法,  如果没有构造方法,使用xml配置的时候需要setter方法)
        private UserDao userDao;
    
        @Override
        public void getUser() {
            System.out.println("1 业务层1 获取user对象...");
            userDao.getUser();
        }
    }

    测试:

        @Test
        public void getUser() throws Exception {
            ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
            UserService userService = ac.getBean("userService", UserService.class);
            userService.getUser();
        }

    运行结果:

    其他注解的使用:

    生命周期注解:

    @PostConstruct 初始化方法

    @PreDestroy 销毁方法

    //Bean的注解
    @Component("springLifeCycle")
    public class SpringLifeCycle {
        //构造方法
        public SpringLifeCycle() {
            System.out.println("SpringLifeCycle 构造...");
        }
    
        //初始化方法的注解
        @PostConstruct
        public void init() {
            System.out.println("SpringLifeCycle 初始化...");
        }
    
        //销毁方法的注解
        @PreDestroy
        public void destroy() {
            System.out.println("SpringLifeCycle 销毁...");
        }
    
        public void helloSpring() {
            System.out.println("hello spring !");
        }
    }

    测试:

        @Test
        public void testLifeCycle() {
            ApplicationContext ac = new ClassPathXmlApplicationContext(
                    "applicationContext.xml");
            SpringLifeCycle springLifeCycle = (SpringLifeCycle) ac.getBean("springLifeCycle");
            springLifeCycle.helloSpring();
    
            // 调用close(ApplicationContext没有close方法,需要转子类调用close)
            ClassPathXmlApplicationContext classAc = (ClassPathXmlApplicationContext) ac;
            classAc.close();
        }

    运行结果:

    Bean的作用域注解:

    还是上面的JavaBean类:

    //Bean的注解
    @Component("springLifeCycle")
    //作用域注解 prototype为多实例,默认为singleton单实例
    @Scope("prototype")
    public class SpringLifeCycle {

    测试:

        @Test
        public void testScope() throws Exception {
            ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
                    "applicationContext.xml");
            SpringLifeCycle lifeCycleBean1 = (SpringLifeCycle) applicationContext
                    .getBean("springLifeCycle");
            SpringLifeCycle lifeCycleBean2 = (SpringLifeCycle) applicationContext
                    .getBean("springLifeCycle");
            System.out.println(lifeCycleBean1);
            System.out.println(lifeCycleBean2);
    
            // 通过反射 代码调用 close方法
            Method closeMethod = applicationContext.getClass().getMethod("close");
            closeMethod.invoke(applicationContext);
        }

    运行结果:

    大家会发现销毁方法没有起作用,这里说明一下,Bean必须为singleton单实例的时候,销毁方法才能执行。

    将scope设置成singleton:

    //Bean的注解
    @Component("springLifeCycle")
    //作用域注解,singleton为默认值,可以不写这个注解
    @Scope("singleton")
    public class SpringLifeCycle {

    执行结果:

  • 相关阅读:
    来一个炫酷的导航条
    jQuery实现瀑布流
    js计时事件
    js浏览器对象的属性和方法
    js对象(一)
    CSS3常用选择器(三)
    软工实践个人总结
    第05组 每周小结 (3/3)
    第05组 每周小结 (2/3)
    第05组 每周小结 (1/3)
  • 原文地址:https://www.cnblogs.com/blazeZzz/p/9305861.html
Copyright © 2020-2023  润新知