1.@component是spring定义的一个通用注解,可以注解任何bean。
2.@scope定义bean的作用域,其默认作用域是”singleton”,除此之外还有prototype,request,session和global session。
案例:@component和@scope用法分析:beanannotation类:
@scope @component public class beanannotation { public void say(string arg) { system.out.println("beanannotation : " + arg); } public void myhashcode() { system.out.println("beanannotation : " + this.hashcode()); } }
junit4测试类→testbeanannotation类:
@runwith(blockjunit4classrunner.class) public class testbeanannotation extends unittestbase { public testbeanannotation() { super("classpath*:spring-beanannotation.xml"); } @test public void testsay() { beanannotation bean = super.getbean("beanannotation"); bean.say("this is test."); } @test public void testscpoe() { beanannotation bean = super.getbean("beanannotation"); bean.myhashcode(); bean = super.getbean("beanannotation"); bean.myhashcode(); } }
spring配置文件→spring-beanannotation.xml:
<context:component-scan base-package="com.beanannotation"></context:component-scan>
我们先从spring配置文件分析,base-package="com.beanannotation"说明我们只处理这个包名下面的注解。
然后分析beanannotation类,有一个say的方法。假设我们不清楚这是一个什么类型(注:service或者dao)的类,我们可以用一个通用的注解@component。
最后分析testbeanannotation类,testsay方法里super.getbean("beanannotation")是从ioc的容器中取到这个bean,并调用bean的say方法。
提出问题的时间到了,当我们super.getbean的时候是通过bean的id从ioc容器中获取的,那么这个id是什么呢?因为在我们添加@component到beanannotation类上的时候,默认的id为beanannotation。如果指定了@component的名称,譬如指定为@component(”bean”)的时候,在单元测试的时候就必须把super.getbean得到的id与之相对应才能测试成功。
在这里我把@scope注解单独分离出来分析,在testbeanannotation类里面有一个testscpoe方法。在beanannotation类里面有一个myhashcode方法,可能大家有些疑惑,为什么要用this.hashcode()?因为@scope指定的是bean的作用域,为了保证测试类的结果准确明了,所以采用哈希码值来判断是否为同一个对象。
3.@repository、@service、@controller是更具有针对性的注解。
ps:这里我们需要明白这三个注解是基于@component定义的注解哦:
①、@repository通常用于注解dao类,也就是我们常说的持久层。
②、@service通常用于注解service类,也就是服务层。
③、@controller通常用于controller类,也就是控制层(mvc)。
4.@autowired理解为“传统”的setter方法,可以用在setter方法上,也可以用在构造器或者成员变量,能够进行spring bean的自动装配。
案例:@autowired用法分析一:spring配置文件→spring-beanannotation.xml:
<context:component-scan base-package="com.beanannotation"></context:component-scan>
simplemovielister类:
public class simplemovielister { private moviefinder moviefinder; @autowired(required=false) public void setmoviefinder(moviefinder moviefinder) { this.moviefinder = moviefinder; } }
在默认的情况下,如果找不到合适的bean将会导致autowiring失败抛出异常,我们可以将@autowired注解在这个set方法上,标记required=false来避免。但是,这不是一个必须的,如果找不到moviefinder的实例,是不会抛出异常的,只有在使用的时候发现moviefinder为null,在这种情况下,就要求我们在使用的时候,首先判断moviefinder是不是为null,如果是就会报空指针异常 。
值得注意的是,我们知道每个类可以有很多个构造器,但是在使用@autowired的时候,有且只能有一个构造器能够被标记为required=true(注:required的默认值为false)。
案例:@autowired用法分析二:beanimplone类:
@order @component public class beanimplone implements beaninterface { }
beanimpltwo类:
@order @component public class beanimpltwo implements beaninterface { }
beaninterface类:
public interface beaninterface { }
beaninvoker类:
@component public class beaninvoker { @autowired private list<beaninterface> list; @autowired private map<string, beaninterface> map; public void say() { if (null != list && 0 != list.size()) { for (beaninterface bean : list) { system.out.println(bean.getclass().getname()); } } else { system.out.println(" list is null !"); } if (null != map && 0 != map.size()) { for (map.entry<string, beaninterface> entry : map.entryset()) { system.out.println(entry.getkey() + " " + entry.getvalue().getclass().getname()); } } else { system.out.println("map is null !"); } } }
测试类testinjection:
@runwith(blockjunit4classrunner.class) public class testinjection extends unittestbase { public testinjection() { super("classpath:spring-beanannotation.xml"); } @test public void testmultibean() { beaninvoker invoker = super.getbean("beaninvoker"); invoker.say(); } }
首先,我们清楚beanimplone类和beanimpltwo类是实现了beaninterface接口的,在beaninvoker类里面我们定义了list和map,我们通过@autowired注解把beanimplone类和beanimpltwo类注解进入其中。那么怎么证实是@autowired注解把这两个类注入到list或者map中的呢?那么请看if循环语句和foreach循环打印,通过这个逻辑判断,如果能够打印出beanimplone类和beanimpltwo类的路径名,就说明这样是可以的。如果有些小伙伴可能不信,那么可以试着不使用@autowired注解,看结果怎么样。
测试类没有什么好说的,各位小伙伴有没有注意到@order注解呢?这里需要解释的就是,如果在@order注解里面输入执行的数字,比如1或者2,那么打印出来的路径名就会按顺序,也就是说通过指定@order注解的内容可以实现优先级的功能。
5.@importresource注解引入一个资源,对应一个xml文件
6.@value注解从资源文件中,取出它的key并赋值给当前类的成员变量
案例:@importresource和@value用法分析:mydrivermanager类:
public class mydrivermanager { public mydrivermanager(string url, string username, string password) { system.out.println("url : " + url); system.out.println("username: " + username); system.out.println("password: " + password); } }
config.xml:
<context:property-placeholder location="classpath:/config.properties"/>
storeconfig类:
@configuration @importresource("classpath:config.xml") public class storeconfig { @value("${jdbc.url}") private string url; @value("${jdbc.username}") private string username; @value("${jdbc.password}") private string password; @bean public mydrivermanager mydrivermanager() { return new mydrivermanager(url, username, password); }
这个案例我们使用注解配置jdbc数据库的连接,首先创建一个内含构造器的mydrivermanager类,然后配置config.xml里面的资源文件路径,以便@importresource注解获取,最后配置storeconfig类。(注意url、username、password也必须要和数据库的保持一致哦)
详解storeconfig类:首先我们定义三个成员变量,然后给每一个成员变量打上一个@value注解,注意@value里面的内容一定是资源文件里面的key值。这里的@importresource注解就是指明一个资源文件,在这个资源文件里面获取到对应的数据。那么@configuration注解是用来干嘛的呢?为什么不用@component注解呢?其实是这样的,@component注解用于将所标注的类加载到 spring 环境中,这时候是需要配置component-scan才能使用的,而@configuration注解是spring 3.x后提供的注解,它用于取代xml来配置 spring。
7.@bean注解用来标识配置和初始化一个由springioc容器管理的新对象的方法,类似xml中配置文件的<bean/>
ps:默认的@bean注解是单例的,那么有什么方式可以指定它的范围呢?所以这里才出现了@scope注解
8.@scope注解,在@scope注解里面value的范围和bean的作用域是通用的,proxymode的属性是采用哪一种的单例方式(一种是基于接口的注解,一种是基于类的代理)
案例:@bean和@scope用法分析: @bean @scope(value ="session",proxymode = "scopedproxymode.target_class") public userpreferences userpreferences(){ return new userpreferences(); } @bean public service userservice(){ userservice service =new simpleuserservice(); service.setuserpreferences(userpreferences); return service; }
以上就是详解spring框架注解的用法代码实例的详细内容。
