[Spring 02] 注解开发
Spring_02
2. 注解
1. Bean的自动装配
spring会在上下文中自动查找,并给bean装配属性
Spring中装配的三种方式:
- XML中显式定义
- java中显示定义
- 隐式的自动装配bean
1. 测试环境:
person: name, cat, dog
cat: sout("miao")
dog: sout("wang")
2. byName(默认是byType)
xml配置中:
<bean id="cat" class="com.roy.pojo.Cat"/>
<bean id="dog" class="com.roy.pojo.Dog"/>
<bean id="person" class="com.roy.pojo.Person" autowire="byName">
<property name="name" value="roy"/>
</bean>
如果把bean中的配置改为:
<bean id="dog1231312312" class="com.roy.pojo.Dog"/>
则无法自动装配
原理: byName装配时,自动匹配 和pojo.Person
里setDog()
方法名中set后面的名称一致的 BeanID;
是区分大小写的,自动把set后面的第一个字母改为小写字母去找。
3. byType
<bean id="person" class="com.roy.pojo.Person" autowire="byType"/>
自动在beans.xml容器中寻找和自己对象属性类型相同的bean进行填充
小结:
- byName 需要所有bean的id唯一,并且这个bean的id需要和自动注入的属性的set方法名一样
- byType 需要所有bean的class唯一,并且这个bean的类型和set方法需要的类型一致
4. 使用注解实现自动装配
@Autowired(required=), @Qualifier(value=), @Resource(name=)
前提:
-
导入context约束:context的三行说明
-
配置注解的支持
<context:annotation-config/>
<?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 https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> <context:annotation-config/> </beans>
-
beans.xml中的配置变为:
<bean id="cat" class="com.roy.pojo.Cat"/> <bean id="dog" class="com.roy.pojo.Dog"/> <bean id="person" class="com.roy.pojo.Person"> <property name="name" value="roy"/> </bean>
pojo中改为:
public class Person { private String name; @Autowired private Cat cat; @Autowired private Dog dog;}
注意:
-
@Autowired建议写在set方法之上,
-
如果pojo中想省略set方法,则set方法要注入的对象(引用类型Cat)必须已经存在于IOC容器中,并且符合byType唯一
-
如果想在不知道容器中是否存在Cat的时候使程序不报异常,注解中添加值:
@Autowired(required=false)
, 当beans.xml中Cat没有被注入时也不会报错。 -
@Autowired默认首先使用ByType,当有多个同类型时,使用byName,当依然无法识别时报错。
-
当有多个同类型的多个id时,用
@Qualifier(value="one of the id")
来指定 -
当有多个同类型的多个id时,用
@Resource(name="one of the id")
来指定//JAVA的原生注解,resource先byName @Resource默认首先使用byName
最初:
@Autowired() //可以通过byType匹配,如果同一类型有多个,使用byName匹配
中间:
@Autowired()//指定类型 @Qualifier(value="") //通过Qualifier指定某个类型中的某个值
最后:
@Resource(name="") //使用原生注解实现两者的合集 //jdk11取消
-
2. 注解开发
环境配置:
- 添加
xmlns:context
- 添加
xsi:schemaLocation
- 添加
<context:component-scan base-package="com.roy.pojo"
, 用于扫描包,此标签包含context的注解配置支持
1.Bean的注解和属性注解
(复杂属性建议走xml配置文件配置)
@Component//添加在pojo类的前面,使用时默认找小写的类名
public class User{
@Value("roy")//也可以放在set方法上面
public String name;
}
3.衍生注解
//当类在不同的包中时,使用不同的注解配置bean,但效果相同,只用于区分在那一层
@Repository//dao层注解
@Service//service层注解
@Controller//controller层注解
效果和@Component一样
4.自动装配(讲过)
5.作用域
在类的上面添加:
@Scope("singleton")
3. javaconfig实现bean装配
方式一:
思想: 把原本的配置xml文件写为一个类,这个类相当于beans.xml文件
-
用@Configuration注解这个类(注解后,这个类也是一个component(看config注解的源码), 首先被spring托管)
-
用@Bean注解类中的方法用来返回装配的bean
-
JavaConfig
@Configuration//注意 public class JavaConfig { @Bean//注意 public User getUser(){//注意:方法名称 return new User();//返回值new一个对象 } }
-
pojo类
public class User { @Value("roy")//注入值 private String name; get/set }
在测试类中,把之前通过CPX获取context对象改为通过注解获取(AnnotationConfigApplicationContext)
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(JavaConfig.class);//注意
User user = (User) context.getBean("getUser");//注意,对应JavaConfig中的方法名称
System.out.println(user.getName());
}
方式二:
同上,
在JavaConfig中添加包扫描,在pojo类上添加@Component, 在方法中修改为获得的小写对象名。
-
JavaConfig.java
@Configuration// @ComponentScan("com.roy.pojo")//添加包扫描 public class JavaConfig { public User getUser(){//取消@Bean return new User(); } }
-
User.java
@Component// 添加组件标签 public class User { @Value("roy") private String name; set/get }
-
MyTest.java
public static void main(String[] args) { ApplicationContext context = new AnnotationConfigApplicationContext(JavaConfig.class); User user = (User) context.getBean("user");// 修改为获得的小写名对象 System.out.println(user.getName()); }
@Import(AnotherJavaConfig.class) 可以导入其他的配置文件;