由于前期不涉及到Web应用,所以不需要配置web.xml.
在src下创建xml(spring-beans.xml)文件。在xml文件中创建beans.
1. 当需要调用的时候,使用
- ApplicationContext ac=new ClassPathXmlApplicationContext("spring-beans.xml");
- ClassPathXmlApplicationContext与WebApplicationContext与FileSystemPathXmlApplicationContext
- WebApplicationContext允许从Web-Inf下开始寻找。
2. 获取beans的三种常用方法
- Dog dog1=(Dog) ac.getBean("dog1");
- Dog dog2=ac.getBean(Dog.class);
- Dog dog3=ac.getBean("dog1",Dog.class);
3. Spring中的依赖注入,有三种
(1)属性注入
set方法
IOC配置文件中,通过
><property name="属性名称" value="属性的值">节点完成注入
需要在类中有set方法
(2)构造器注入
><使用construstor-arg value="" index=""></construstor-arg>
遇到多参数的实体类,多使用几个construstor. 如果该实体类的参数有其他类的实例,那么再注入的时候,需要在A bean中引用 B bean的实例。使用引用<ref bean="car1">.
也可以按照使用入参的类型来注入。
在注入value的时候,遇到特殊的值,可以使用<!CDATA[]>来传值,进行强制解析。
(3)工厂方法注入--很少使用
4. 内部bean.类似于内部类,当bean A只会被 bean B 引用
5. bean可以使用自动装配,需要在bean的autowire 属性指定自动装配的模式。二者不可兼容。
byType模式:若IOC容器中有多个与目标Bean类型一致的Bean,将无法判断哪个bean最合适
byName模式: 必须将目标Bean的名称与属性名设置的一样。
缺点:不够灵活,当属性过多时候,会都进行装配,导致过重。
autowire只能二者选一,不能兼容。
在实际开发中,清晰明确的配置文件更好。
6. bean的作用域分四种:
(1)Signleton IOC容器默认作用域是单实例bean,当容器加载时候只会创建唯一一个实例。整个IOC容器范围都能共享该实例。后续所有调用bean都将返回一个对象。
(2)prototype.每次调用都会返回一个新的对象
(3)request 每次Http请求都会创建一个新的Bean,但是该作用域仅仅适用于WebApplicationContext.
(4)session,同一个Http Session共享一个Bean,该作用域仅仅适用于WebApplicationContext.
7. 引用外部属性文件,完成属性注入。实现解耦操作,每次修改不需要改动xml文件。例如数据源对象,不能写在xml文件中。Sping提供了一个PropertyPlaceholderConfigurer的BeanFactory后置处理器。这个处理器允许将value移动到外部文件中。
(1)创建 *.properties. key=value
(2)在xml中,引用key需要使用${}。
(3)告知IOC容器需要使用的properties文件
- <context:property-placeholder location="classpath:person.properties"/>
8. springEL表达式:
(1)访问bean中的某个属性。如#{person1.name}
(2) 可以进行基本的运算,如加减乘除等。如 #{person1.age *10}
9. Bean的生命周期,spring允许在bean的生命周期的特定点执行特定的任务。
生命周期包括:
(1) 通过构造器方法或者工厂方法创建bean
(2)为bean的属性设置值和对其他bean的引用
(3)后置处理器前置处理
(4)调用bean的初始化方法 init-method
(5)后置处理器后置处理
>后置处理实现postPorcessAfterInitialization(Object bean,String beanName)
(7)调用bean的销毁化方法destory-method
10. 后置处理器
(1).bean后置处理器允许在调用初始化方法前后对bean进行额外处理
(2).bean后置处理器对所有bean实例逐一处理,而非单一实例。例如根据某些标准更改bean属性。
(3).对bean后置处理器,需要实现beanPostProcessor接口。
(4).前置处理实现 postPorcessBeforeInitialization(Object bean,String beanName)
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
System.out.println("之前");
return bean;
}
(5).后置处理实现postPorcessAfterInitialization(Object bean,String beanName)
@Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
System.out.println("之后");
return bean;
}
(6). 在spring-bans.xml中为该处理器设置bean.
<bean id="beanProcessor" class="com.spring.beans.MyBeanProcessor"/>
11. 静态工厂方法与实例工厂方法创建bean
(1)区别:静态工厂通过类名直接就去调用,在调用的时候已经存在一个工厂,而实例工厂需要在调用的时候先去创建工厂。
(2)静态工厂方法创建bean:
<bean id="dateFormat" class="java.text.DateFormat" factory-method="getDateInstance">
<constructor-arg value="2"></constructor-arg>
</bean>
调用:
DateFormat df=(DateFormat) ac.getBean("dateFormat");
(3)实例工厂方法创建Bean,将对象的创建过程封装在另外一个对象实例中,当需要请求该对象的时候,只需要简单的调用该实例方法而不需要关心对象的创建过程,实现解耦操作。
<bean id="simpleDateFormat" class="java.text.SimpleDateFormat">
<constructor-arg value="yyyy-MM-dd hh-mm-ss"></constructor-arg>
</bean>
<bean id="date" factory-bean="simpleDateFormat" factory-method="parse">
<constructor-arg value="2012-12-12 12-12-12"></constructor-arg>
</bean>
在创建date的时候,只需要指定方法名,加上参数。而不需要关注具体使用的是那种类。
12. 通过FactoryBean的方式来创建bean.
需要创建一个类,继承FactoryBean。
public class MyFactoryBean implements FactoryBean<Object> {
@Override
public Object getObject() throws Exception {
Dog dog=new Dog();
dog.setType("博美");
return dog;
}
@Override
public Class<?> getObjectType() {
return Dog.class;
}
@Override
public boolean isSingleton() {
// TODO Auto-generated method stub
return false;
}
}
13. 使用注解方式自动装配bean
(1)在pring-beans.xml中,增加自动扫描包
<context:component-scan base-package="com.spring.beans"></context:component-scan>
(2)在实体中使用@component. 如果不指定id,默认是类名的首字母小写。
(3)同理,还有其他的注解。@Controller,用来配置action控制层。@service用来代表业务层。@Repository用来标注dao层。
14. 使用注解方式自动注入bean的属性
(1) @Autowired.按照类型自动注入,如果IOC容器中存在多个类型,抛出异常。Autowird会有很多问题,一般不常见
@Autowired
private MyDao myDao;
(2)@Resource按照名字来装配。
(3)@Inject跟@Autowired类似,但是没有required的属性,当required=false,表示不需要进行注入。
15. AOP
切面(Aspect) 横切关注点的模块化(抽象),具有相同功能的模块点可以抽象成一个切面。比如校验数据模块与日志加载模块可以抽象成两个切面。
连接点:spring允许加入通知的地方:,共同业务和核心业务分离的点。前置、后置、异常处理等。
切点:可以通过切点定位到某一个特定的连接点。
(1) 先创建一个Aspect类,用来存放具体分离开的代码。
(2)共同的业务加入到切面,
(3)前置通知、后置通知。@Before
//引用注解,表示该方法是切面
@Aspect@Component
public class ComputerAspect {
/**
* execution(public void com.spring.beans.service.impl.ComputerServiceImpl.add())
* 这是切点表达式,将需要处理的function全路径放在这里。
* 如果需要加参数,可以使用类似add(int,int)
*/
@Before(value = "execution(public void com.spring.beans.service.impl.ComputerServiceImpl.add())")
public void before(){
System.out.println("调用function之前");
}
@After("execution(public void com.spring.beans.service.impl.ComputerServiceImpl.add())")
public void after(){
System.out.println("调用function之后");
}
}
(4)在spring-ban.xml中,增加切面标签。aspect注解的类自动生成代理。
<app:aspect-autoproxy></app:aspect-autoproxy>
记得导入AOP的命名空间与AOP的xsd文件。