文章目录
- 实验九:基于XML的自动装配
- 实验十:通过注解创建Dao、Service、Controler
- 实验十一:使用context:exclude-filter指定扫描包时不包含的类
- 实验十二:使用context:include-filter指定扫描包时要包含的类
- 实验十三:使用@Autowired注解实现根据类型自动装配
- 实验十四:Autowired和Resource的区别
实验九:基于XML的自动装配
现在有一个Persion类和一个汽车Car类,在xml进行如下手动装配:
<bean id="car" class="com.gql.bean.Car">
<property name="carName" value="宝马"></property>
<property name="color" value="白色"></property>
</bean>
<bean id="Persion" class="com.gql.bean.Persion">
<property name="car" ref="car"></property>
</bean>
测试:
@Test
public void test13() {
Persion p = ioc.getBean(Persion.class);
System.out.println(p);
}
成功通过手动装配的形式将car赋值给了Persion:
自动装配通俗的说就是为自定义类型自动赋值。
bean中有一个autowire属性可以实现自动装配:
- autowire=“default/no”:不自动装配。
- autowire=“byName”:按照名字装配。在容器中找到一个名为"byName"的组件,为其赋值。
- autowire=“byType”:以属性的类型为依据去容器中找到这个组件。(有多个会报错)
- autowire=“constructor”:按照构造器进行赋值,先按照有参构造器参数的类型装配,没有就直接为组件装配null。如果按照类型找到多个,参数的名称为id继续匹配。不会报错。
- 如果有一个List,容器可以把容器中所有的book封装给List。
实验十:通过注解创建Dao、Service、Controler
通过在bean上添加下面的注解,可以快速的将bean添加到ioc容器中。
- @Controller:给控制器层(Servlet)的组件加这个注解。
- @Service:给业务逻辑层的组件加这个注解。
- @Repository:为数据库层/持久化层(Dao)的组件添加这个注解。
- @Component:为不属于以上几层的组件添加这个注解。
实际上,标志任何一个注解都能快速的将这个组件加到ioc容器中,但还是建议按照约定来。
使用注解将组件快速加入容器需要几个步骤:
步骤1:给要添加的组件标四个注解中的任何一个。
步骤2:使用context:component-scan
进行扫描,告诉Spring,自动扫描加了注解的组件。(base-package=“xxx”:指定扫描的基础包,把基础包及其下面的所有包中加了注解的类,自动的扫描进ioc容器中)。
步骤3:使用注解模式一定要导入AOP包。
使用注解和xml配置的默认配置是一样的:
- bean的id默认就是类名首字母小写。(可以在注解后面加小括号进行更改:例如:@Repository(“newdao”))
- 组件的作用域默认是单例的。(可以增加@Scope(value = “prototype”)注解,更改为多实例)
实验十一:使用context:exclude-filter指定扫描包时不包含的类
<context:component-scan base-package="com.gql">
<!-- 按照注解进行排除,expression中填写的都是全类名。 -->
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
- type=“annotation”(常用) :按照注解进行排除,标注了指定注解的组件不要
- type=“assignable”(常用) :按照类排除,指定排除某个具体的类
- type=“aspectj” :aspectj表达式
- type=“custom” :自定义接口TypeFilter,决定哪些使用
- type=“regex” :使用正则表达式
实验十二:使用context:include-filter指定扫描包时要包含的类
context:include-filter的用法和context:exclude-filter的用法相反,不过需要注意的是,使用context:include-filter时需要将use-default-filters设置为false,表示关闭默认扫描规则。
<context:component-scan base-package="com.gql" use-default-filters="false">
<!-- 指定只扫描哪些组件 -->
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
实验十三:使用@Autowired注解实现根据类型自动装配
进行一个@Autowired的演示:
在容器中添加扫描组件:
<?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 http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd">
<!-- 自动扫描组件 -->
<context:component-scan base-package="com.gql">
</context:component-scan>
</beans>
控制层:
@Controller
public class BookServlet {
@Autowired
private BookService bookservice;
public void doGet() {
bookservice.save();
}
}
业务逻辑层:
@Service
public class BookService {
@Autowired
private BookDao bookDao;
public void save() {
System.out.println("正在调用BookDao进行保存图书..");
bookDao.saveBook();
}
}
数据访问层:
@Repository
public class BookDao {
public void saveBook() {
System.out.println("图书保存成功...");
}
}
测试:
@Test
public void test01() {
BookServlet bookServlet = ioc.getBean(BookServlet.class);
bookServlet.doGet();
}
调用测试方法,成功传递成功。
@Autowired的原理:
先按照类型去容器中找到对应的组件,找到就赋值,找不到抛出异常,找到多个就按照变量名作为id进行匹配(若还是匹配不到,使用@Qualifier(“xxx”)指定一个新的名字作为id。若@Qualifier找到就装配,找不到就报错)。
- @Autowired标注的自动装配的默认属性是一定装配上的,找不到就报错。
- 也可以使用@Autowired(“required=false”),使得找不到就装配null。
- 其中的@Qualifier注解不仅可以标注在属性上,还可以标注在方法上和方法的形参位置上。
实验十四:Autowired和Resource的区别
- @Autowired(最强大)
- @Resource
- @Inject
三者都是自动装配的意思,
@Autowired是Spring的注解,三者中功能最强大。
@Resource是J2EE自带的注解(其中没有required属性),可以理解为阉割版@Autowired。@Inject 是EJB环境下开发使用。
@Autowired离开Spring就不能使用了,@Resource是Java的标准,其扩展性很强,如果切换容器框架,@Resource还是可以使用的。话虽这样讲,但是容器矿建方面,抛开EJB,实际上是Spring一家独大。