首先理解什么是Bean。凡是有方法或属性的类都需要实例化,这样才能具象化去使用这些方法和属性,把Bean理解为类的代理或代言人(实际上确实是通过反射、代理来实现的),这样它就能代表类拥有该拥有的东西了,就可以去使用了。什么是注解。注解就是@XX,如果你使用@XX,Spring就会过来看看,帮你注册一个Bean或者从Spring IOC中拿Bean。
大体上注解分成两种。一是注册Bean,就是将你的类或者方法转化成一个Bean,注册到Spring IOC中,如@Component , @Repository , @ Controller , @Service;另一种,就是从Spring IOC中获取一个Bean,如@Autowired , @Resource。
前期准备
打算使用代码来讲解注解,这就需要先创建例程:
有Tiger,Monkey,ICar,BenzCar,BMWCar
public class Tiger {
private String tigerName="TigerKing";
public String toString(){
return "TigerName:"+tigerName;
}
}
public class Monkey {
private String monkeyName = "MonkeyKing";
public String toString(){
return "MonkeyName:" + monkeyName;
}
}
public interface ICar {
public String getCarName();
}
public class BenzCar implements ICar{
public String getCarName(){
return "Benz car";
}
}
public class BMWCar implements ICar{
public String getCarName(){
return "BMW car";
}
}
常用的注解
1、@Autowired
顾名思义,自动装配。按照类型匹配,在容器中查找匹配的Bean。当有且仅有一个匹配的Bean时,Spring将其注入@Autowired标注的变量中。
先注册一些Bean。包括tiger和monkey
<?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" />
<bean id="tiger" class="com.spring.model.Tiger" />
<bean id="monkey" class="com.spring.model.Monkey" />
</beans>
如果不是Spring,那我们使用的时候就是 Tiger tiger = new Tiger( )。@Autowired十分方便我们将获取实例。
public class Zoo {
@Autowired
private Tiger tiger;
@Autowired
private Monkey monkey;
}
@Autowired会自动匹配类型,并自动注入进来。如果没有事先注入的Bean,而使用@Autowired就会在编译时候报错,有没有优化方法,有。
@Autowired(required=false)
private Tiger tiger;
这样在找不到Bean时也不会报错,只不过tiger属性为null。
2、@Qualifier
如果容器中有一个以上匹配的Bean,则可以通过@Qualifier注解限定Bean的名称。
向Spring IOC添加新的注解,宝马车和奔驰车,这两个车都是继承ICar。
<bean id="bmwCar" class="com.spring.service.impl.BMWCar" />
<bean id="benz" class="com.spring.service.impl.BenzCar" />
如果你正好要出行,这个时候需要一个车,好,获取一个呗:
@Autowired
private ICar car;
这个时候Spring这个管家就生气了,什么鬼,到底什么车,奔驰还是宝马。如果说ICar只有一个继承实现类,那好说,直接使用一个就好了。但是多个实现就有问题了,不知道使用那个实现类。这个时候使用@Qualifier 来指明使用哪个Bean。所以决定以后出行都用宝马。此处会注入名为”bmwCar”的Bean。
@Autowired
@Qualifier("bmwCar")
private ICar car;
3、@Resource
这个@Resource注解与@Autowired注解作用非常相似。
@Resource(name="tiger")
private Tiger tiger;
@Resource(type=Monkey.class)
private Monkey 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的注解,这个看一下导入注解的时候这两个注解的包名就一清二楚了
4、@Service
通过上面的例子会发现,好累,每次都要写个xml去存放Spring的Bean,一旦项目变大,那这个xml会变得非常庞大和复杂,难以维护。有没有方法解决,有的。@Service。@Service的作用就是将注解的地方生成一个Bean注册到Spring IOC中管理。
@Service
public class Monkey {
private String monkeyName = "MonkeyKing";
public String toString(){
return "MonkeyName:" + monkeyName;
}
}
上述就是将Monkey这个类生成一个Monkey Bean注册到Spring IOC中。@Service注解,其实做了两件事情:
1. 声明Monkey.java是一个bean,这点很重要,因为Monkey.java是一个bean,其他的类才可以使用@Autowired将Monkey作为一个成员变量自动注入。
2. Monkey.java在bean中的id是”monkey”,即类名且首字母小写。
如果有一些特殊的癖好,我不要小猴,我要大猴,怎么办,那就注册的时候指定名称@Service(“Monkey”)。
5、@Scope
Spring 管家有一个有癖好的人。Spring默认产生的bean是单例的。默认是”singleton”即单例,”prototype”表示原型即每次都会new一个新的出来。
@Service("monkey")
@Scope("prototype")
public class Monkey {
private String monkeyName = "MonkeyKing";
public String toString(){
return "MonkeyName:" + monkeyName;
}
}
6、@Controller
@Controller对应表现层的Bean,也就是Action。这个也是与@Service相似,向Spring注册一个Bean,@Service是对应的是业务层Bean。
7、@ Repository
@Repository对应数据访问层Bean。
@Repository("userDao")
public class UserDaoImpl implements BaseDao {
………
}
@Repository(“userDao”)注解是告诉Spring,让Spring创建一个名字叫”userDao”的UserDaoImpl实例。
当需要使用Spring创建的名字叫”userDao”的UserDaoImpl实例时,就可以使用@Autowired(“userDao”)注解告诉Spring,Spring把创建好的userDao注入即可。
@Autowired("userDao")
private BaseDao userDao;
@Repository,@Service和@Controlle这三个没什么功能上的差别,差别只是在语义上,@Repository/@Service/@Controller分别代表了特定语义的类, @Repository:用于标注数据访问组件,即DAO组件我们注解这个类,更多的是对它有个数据库操作的管理,比如你继承了spring自己的hibernateDAo这样的东西,那怎么给你注入一些数据库操作的元素了,就靠它了,所以这个不是随便注释的。