zoukankan      html  css  js  c++  java
  • spring注解使用

    一、原始创建对象

    属性注入介绍

    属性注入的xml方式介绍(介绍常用的两种方式)

    (1)使用set方法注入

    (2)使用有参数构造注入

    1、@Autowired

    package com.spring.model;
    
    public class Tiger {
        
        private String tigerName="TigerKing";
        
        public String toString(){
            return "TigerName:"+tigerName;
        }
    }
    package com.spring.model;
    
    public class Monkey {
        
        private String monkeyName = "MonkeyKing";
        
        public String toString(){
            return "MonkeyName:" + monkeyName;
        }
    
    }

    @Autowired顾名思义,就是自动装配,其作用是为了消除代码Java代码里面的getter/setter与bean属性中的property。当然,getter看个人需求,如果私有属性需要对外提供的话,应当予以保留。

    @Autowired默认按类型匹配的方式,在容器查找匹配的Bean,当有且仅有一个匹配的Bean时,Spring将其注入@Autowired标注的变量中。

    注意:使用注解的时候,需要在配置文件中配置扫描包路径:<context:component-scan base-package="com.spring" />里面的base-package是扫描的包的路径可以使用匹配符

    例如:com.spring.*

    因此,引入@Autowired注解,先看一下spring配置文件怎么写:

    <beans
    xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd
    ">

    <context:component-scan base-package="com.spring" />
    <bean id="tiger" class="com.spring.model.Tiger" />
    <bean id="monkey" class="com.spring.model.Monkey" />

    </beans>

    package com.spring.model;
    
    import org.springframework.beans.factory.annotation.Autowired;
    
    public class Zoo {
        
        @Autowired
        private Tiger tiger;
        
        @Autowired
        private Monkey monkey;
        
        public String toString(){
            return tiger + "
    " + monkey;
        }
        
    }
    

     这里@Autowired注解的意思就是,当Spring发现@Autowired注解时,将自动在代码上下文中找到和其匹配(默认是类型匹配)的Bean,并自动注入到相应的地方去。

    当xml配置文件中Tiger和Monkey的Bean定义都给去掉了,Spring容器找不到也很好理解。那么,如果属性找不到我不想让Spring容器抛出异常,而就是显示null,可以吗?可以的,其实异常信息里面也给出了提示了,就是将@Autowired注解的required属性设置为false即可:

    package com.spring.model;
    
    import org.springframework.beans.factory.annotation.Autowired;
    
    public class Zoo {
        
        @Autowired(required=false)
        private Tiger tiger;
        
        @Autowired(required=false)
        private Monkey monkey;
        
        public String toString(){
            return tiger + "
    " + monkey;
        }
        
    }

    2、Resource

    @Resource注解与@Autowired注解作用非常相似看例子:

    package com.spring.model;
    
    import javax.annotation.Resource;
    
    public class Zoo1 {
        
        @Resource(name="tiger")
        private Tiger tiger;
        
        @Resource(type=Monkey.class)
        private Monkey monkey;
        
        public String toString(){
            return tiger + "
    " + monkey;
        }
    }

    这是详细一些的用法,说一下@Resource的装配顺序:
    (1)、@Resource后面没有任何内容,默认通过name属性去匹配bean,找不到再按type去匹配
    (2)、指定了name或者type则根据指定的类型去匹配bean
    (3)、指定了name和type则根据指定的name和type去匹配bean,任何一个不匹配都将报错

    然后,区分一下@Autowired和@Resource两个注解的区别:
    (1)、@Autowired默认按照byType方式进行bean匹配,@Resource默认按照byName方式进行bean匹配
    (2)、@Autowired是Spring的注解,@Resource是J2EE的注解,这个看一下导入注解的时候这两个注解的包名就一清二楚了

    3、Service

    上面这个例子,还可以继续简化,因为spring的配置文件里面还有两个bean,下一步的简化是把这两个个bean也给去掉,使得spring配置文件里面只有一个自动扫描的标签,增强Java代码的内聚性并进一步减少配置文件。

    要继续简化,可以使用@Service。先看一下配置文件,当然是全部删除了:

    <?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:p="http://www.springframework.org/schema/p"
        xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.0.xsd
        ">
        
        <context:component-scan base-package="com.spring" />
        
    </beans>
    package com.spring.model;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    @Service
    public class Zoo {
        
        @Autowired
        private Tiger tiger;
        
        @Autowired
        private Monkey monkey;
        
        public String toString(){
            return tiger + "
    " + monkey;
        }
        
    }

    这样,Zoo.java在Spring容器中存在的形式就是"zoo",即可以通过ApplicationContext的getBean("zoo")方法来得到Zoo.java。@Service注解,其实做了两件事情:
    (1)、声明Zoo.java是一个bean,这点很重要,因为Zoo.java是一个bean,其他的类才可以使用@Autowired将Zoo作为一个成员变量自动注入。
    (2)、Zoo.java在bean中的id是"zoo",即类名且首字母小写。

    如果,我不想用这种形式怎么办,就想让Zoo.java在Spring容器中的名字叫做"Zoo",可以的:

    package com.spring.model;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Scope;
    import org.springframework.stereotype.Service;
    
    @Service("Zoo")
    @Scope("prototype")
    public class Zoo {
        
        @Autowired
        private Tiger tiger;
        
        @Autowired
        private Monkey monkey;
        
        public String toString(){
            return tiger + "
    " + monkey;
        }
        
    }

    这样,就可以通过ApplicationContext的getBean("Zoo")方法来得到Zoo.java了。

    这里我还多加了一个@Scope注解,应该很好理解。因为Spring默认产生的bean是单例的,假如我不想使用单例怎么办,xml文件里面可以在bean里面配置scope属性。注解也是一样,配置@Scope即可,默认是"singleton"即单例,"prototype"表示原型即每次都会new一个新的出来。

    使用注解来构造IoC容器
    用注解来向Spring容器注册Bean。需要在applicationContext.xml中注册<context:component-scan base-package=”pagkage1[,pagkage2,…,pagkageN]”/>。

    如:在base-package指明一个包

    <context:component-scan base-package="cn.gacl.java"/>

    表明cn.gacl.java包及其子包中,如果某个类的头上带有特定的注解【@Component/@Repository/@Service/@Controller】,就会将这个对象作为Bean注册进Spring容器。也可以在<context:component-scan base-package=” ”/>中指定多个包,如:

    <context:component-scan base-package="cn.gacl.dao.impl,cn.gacl.service.impl,cn.gacl.action"/>

    多个包逗号隔开。

    4、@Component
    @Component是所有受Spring 管理组件的通用形式,@Component注解可以放在类的头上,@Component不推荐使用。

    5、@Controller
    @Controller对应表现层的Bean,也就是Action,例如:

    @Controller
    @Scope("prototype")
    public class UserAction extends BaseAction<User>{
     ……
    }

    使用@Controller注解标识UserAction之后,就表示要把UserAction交给Spring容器管理,在Spring容器中会存在一个名字为"userAction"的action,这个名字是根据UserAction类名来取的。注意:如果@Controller不指定其value【@Controller】,则默认的bean名字为这个类的类名首字母小写,如果指定value【@Controller(value="UserAction")】或者【@Controller("UserAction")】,则使用value作为bean的名字。

    这里的UserAction还使用了@Scope注解,@Scope("prototype")表示将Action的范围声明为原型,可以利用容器的scope="prototype"来保证每一个请求有一个单独的Action来处理,避免struts中Action的线程安全问题。spring 默认scope 是单例模式(scope="singleton"),这样只会创建一个Action对象,每次访问都是同一Action对象,数据不安全,struts2 是要求每次次访问都对应不同的Action,scope="prototype" 可以保证当有请求的时候都创建一个Action对象。

    6、@Service
    @Service对应的是业务层Bean,例如:

     

    @Service("userService")
    public class UserServiceImpl implements UserService {
    ………
    }

     

    @Service("userService")注解是告诉Spring,当Spring要创建UserServiceImpl的的实例时,bean的名字必须叫做"userService",这样当Action需要使用UserServiceImpl的的实例时,就可以由Spring创建好的"userService",然后注入给Action:在Action只需要声明一个名字叫"userService"的变量来接收由Spring注入的"userService"即可,具体代码如下:

    // 注入userService
    @Resource(name = "userService")
    private UserService userService;

    注意:在Action声明的"userService"变量的类型必须是"UserServiceImpl"或者是其父类"UserService",否则由于类型不一致而无法注入,由于Action中的声明的"userService"变量使用了@Resource注解去标注,并且指明了其name = "userService",这就等于告诉Spring,说我Action要实例化一个"userService",你Spring快点帮我实例化好,然后给我,当Spring看到userService变量上的@Resource的注解时,根据其指明的name属性可以知道,Action中需要用到一个UserServiceImpl的实例,此时Spring就会把自己创建好的名字叫做"userService"的UserServiceImpl的实例注入给Action中的"userService"变量,帮助Action完成userService的实例化,这样在Action中就不用通过"UserService userService = new UserServiceImpl();"这种最原始的方式去实例化userService了。如果没有Spring,那么当Action需要使用UserServiceImpl时,必须通过"UserService userService = new UserServiceImpl();"主动去创建实例对象,但使用了Spring之后,Action要使用UserServiceImpl时,就不用主动去创建UserServiceImpl的实例了,创建UserServiceImpl实例已经交给Spring来做了,Spring把创建好的UserServiceImpl实例给Action,Action拿到就可以直接用了。Action由原来的主动创建UserServiceImpl实例后就可以马上使用,变成了被动等待由Spring创建好UserServiceImpl实例之后再注入给Action,Action才能够使用。这说明Action对"UserServiceImpl"类的“控制权”已经被“反转”了,原来主动权在自己手上,自己要使用"UserServiceImpl"类的实例,自己主动去new一个出来马上就可以使用了,但现在自己不能主动去new "UserServiceImpl"类的实例,new "UserServiceImpl"类的实例的权力已经被Spring拿走了,只有Spring才能够new "UserServiceImpl"类的实例,而Action只能等Spring创建好"UserServiceImpl"类的实例后,再“恳求”Spring把创建好的"UserServiceImpl"类的实例给他,这样他才能够使用"UserServiceImpl",这就是Spring核心思想“控制反转”,也叫“依赖注入”,“依赖注入”也很好理解,Action需要使用UserServiceImpl干活,那么就是对UserServiceImpl产生了依赖,Spring把Acion需要依赖的UserServiceImpl注入(也就是“给”)给Action,这就是所谓的“依赖注入”。对Action而言,Action依赖什么东西,就请求Spring注入给他,对Spring而言,Action需要什么,Spring就主动注入给他。

    7、@ Repository
    @Repository对应数据访问层Bean ,例如:

    @Repository(value="userDao")
    public class UserDaoImpl extends BaseDaoImpl<User> {
    ………
    }

    @Repository(value="userDao")注解是告诉Spring,让Spring创建一个名字叫"userDao"的UserDaoImpl实例。

    当Service需要使用Spring创建的名字叫"userDao"的UserDaoImpl实例时,就可以使用@Resource(name = "userDao")注解告诉Spring,

    Spring把创建好的userDao注入给Service即可。

    // 注入userDao,从数据库中根据用户Id取出指定用户时需要用到
    @Resource(name = "userDao")
    private BaseDao<User> userDao;

    Spring常用注解汇总 

    @Controller,@Service,@Repository,@Component都可以指定value的值来定义spring容器中的bean的id值
    本文汇总了Spring的常用注解,以方便大家查询和使用,具体如下:

    使用注解之前要开启自动扫描功能,其中base-package为需要扫描的包(含子包)。

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

    @Configuration把一个类作为一个IoC容器,它的某个方法头上如果注册了@Bean,就会作为这个Spring容器中的Bean。
    @Scope注解 作用域
    @Lazy(true) 表示延迟初始化
    @Service用于标注业务层组件、 
    @Controller用于标注控制层组件(如struts中的action)
    @Repository用于标注数据访问组件,即DAO组件。
    @Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。
    @Scope用于指定scope作用域的(用在类上)
    @PostConstruct用于指定初始化方法(用在方法上)
    @PreDestory用于指定销毁方法(用在方法上)
    @DependsOn:定义Bean初始化及销毁时的顺序
    @Primary:自动装配时当出现多个Bean候选者时,被注解为@Primary的Bean将作为首选者,否则将抛出异常
    @Autowired 默认按类型装配,如果我们想使用按名称装配,可以结合@Qualifier注解一起使用。如下:
    @Autowired @Qualifier("personDaoBean") 存在多个实例配合使用
    @Resource默认按名称装配,当找不到与名称匹配的bean才会按类型装配。
    @PostConstruct 初始化注解
    @PreDestroy 摧毁注解 默认 单例  启动就加载
    @Async异步方法调用

     

  • 相关阅读:
    day 66 crm(3) 自创组件stark界面展示数据
    day 65 crm(2) admin源码解析,以及简单的仿造admin组件
    用 Python+nginx+django 打造在线家庭影院
    django -admin 源码解析
    day 64 crm项目(1) admin组件的初识别以及应用
    云链接 接口不允许 情况 解决方法 mysql Host is not allowed to connect to this MySQL server解决方法
    day 56 linux的安装python3 ,虚拟环境,mysql ,redis
    day55 linux 基础以及系统优化
    Codeforces 989 P循环节01构造 ABCD连通块构造 思维对云遮月参考系坐标轴转换
    Codeforces 990 调和级数路灯贪心暴力 DFS生成树两子树差调水 GCD树连通块暴力
  • 原文地址:https://www.cnblogs.com/ya-qiang/p/9325698.html
Copyright © 2011-2022 走看看