1.搭建spring运行环境
1.1.导入jar包
spring包:
SPRING_HOME/dist/org.springframework.asm-3.1.3.RELEASE.jar
SPRING_HOME/dist/org.springframework.beans-3.1.3.RELEASE.jar
SPRING_HOME/dist/org.springframework.context-3.1.3.RELEASE.jar
SPRING_HOME/dist/org.springframework.core-3.1.3.RELEASE.jar
SPRING_HOME/dist/org.springframework.expression-3.1.3.RELEASE.jar
log4j包:
log4j-1.2.17.jar
commons-logging:
commons-logging-1.1.1.jar
1.2.加入配置文件
SPRING_HOME/project/.../...context.xml(applicationContext-bean.xml)
最简单的配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<bean id="person" class="com.spring.pojo.Person">
<!-- bean 的内容 -->
</bean>
</beans>
需要使用annotation的配置文件:
<?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-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
</beans>
需要使用aspect的配置文件:
<?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"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
<aop:aspectj-autoproxy/>
</beans>
1.3.测试运行环境
@Test
public void testBean() throws Exception {
ApplicationContext ac = new ClassPathXmlApplicationContext(
new String[] { "applicationContext-bean.xml" });
Person p = (Person) ac.getBean("person");
System.out.println(p.getClass().getName());
p.getClass().newInstance().say();
}
2.spring中创建bean实例的3中方式
2.1.使用构造器实例化(最常用的一种方式)
<bean id="person" class="com.spring.pojo.Person"></bean>
2.2.使用静态工厂方法实例化
public class PersonFactory {
public static Person createPerson(){//注意,该方法应该是static的
return new Person();
}
}
//注意class对应的名称应该是factory的类。
<bean id="person2" class="com.spring.pojo.PersonFactory" factory-method="createPerson">
<!-- bean 的内容 -->
</bean>
2.3.使用实例化工厂方法实例化
先实例化一个工厂bean,在使用该工厂bean去实例化需要的bean
public class PersonFactory {
public Person createPerson(){//注意,该方法不是static的
return new Person();
}
}
//注意class对应的名称应该是factory的类。factor-bean对应的是factoryBean的id。
<bean id="personFactory" class="com.spring.pojo.PersonFactory"></bean>
<bean id="person3" factory-bean="personFactory" factory-method="createPerson"></bean>
3.spring中bean的作用域(scope)
.singleton 默认情况得到的是相同的对象(单实例)
<bean id="person" class="com.spring.pojo.Person"></bean>//默认可以不用写
Person p1 = (Person) ac.getBean("person");
Person p2 = (Person) ac.getBean("person");
System.out.println(p1 == p2);//true
.prototype 每次从容器中得到的都是新的对象
<bean id="person" class="com.spring.pojo.Person" scope="prototype"></bean>
System.out.println(p1 == p2);//false
//默认情况下lazy-init="false",不延迟加载。可以设置lazy-init="true";
//下面是web应用中使用到。
.request
.session
.global session(application)
4.spring中管理bean的生命周期
4.1.lazy-init="default"(默认情况下)
当scope="singleton"时,在初始化spring容器的时候,在加载完xml配置文件后会实例化所有配置文件中的class
当scopt="prototype"时,在getBean()方法调用的时候才会进行实例化
4.2.lazy-init="true"
此时,无论scope的值为什么,都会延迟初始化,在getBean()时才实例化,一般不推荐使用。
4.3.实例化之后执行init()方法(init-method)
<bean id="person" class="com.spring.pojo.Person" lazy-init="false" init-method="init"></bean>
4.4.实例对象被摧毁是执行destroy()方法(destroy-method)
<bean id="person" class="com.spring.pojo.Person" lazy-init="false" destroy-method="destroy"></bean>
当AbstractApplicationContext执行.close()或者.destroy()时调运。
输出结果顺序:正在实例化Person对象 正在初始化。。。正在摧毁。。。
5.spring中的bean注入依赖对象
5.1.使用属性的Setter方法注入。
public class PersonServiceImpl implements PersonService {
private String name;
private PersonDao personDao;
private Set<String> sets = new HashSet<String>();
private List<String> lists = new ArrayList<String>();
private Map<Integer, String> maps = new HashMap<Integer, String>();
private Properties properties = new Properties();
//setter/getter
}
基本类型属性的注入:(使用value属性)
<bean id="personService" class="com.spring.service.impl.PersonServiceImpl">
<property name="name" value="gusi"></property>
</bean>
其他bean属性的注入:
方法一:使用ref属性引用其他bean方式(通过反射,使用setXxx()方法注入)
<bean id="personDao" class="com.spring.dao.impl.PersonDaoImpl"></bean>
<bean id="personService" class="com.spring.service.impl.PersonServiceImpl">
<property name="personDao" ref="personDao"></property>
</bean>
方法二:使用内部bean注入(该bean不能被其他bean使用)
<bean id="personService" class="com.spring.service.impl.PersonServiceImpl">
<property name="personDao">
<bean class="com.spring.dao.impl.PersonDaoImpl"></bean>
</property>
</bean>
注入各种集合:
set集合:
<property name="sets">
<set>
<value>first</value>
<value>third</value>
<value>second</value>
</set>
</property>
list集合:
<property name="lists">
<list>
<value>第一个</value>
<value>第二个</value>
<value>第三个</value>
</list>
</property>
map集合:
<property name="maps">
<map>
<entry key="1" value="value1"></entry>
<entry key="2" value="value2"></entry>
<entry key="3" value="value3"></entry>
</map>
</property>
Properties对象:
<property name="properties">
<props>
<prop key="1">java</prop>
<prop key="2">web</prop>
</props>
</property>
5.2.使用带参构造器注入。
public class PersonServiceImpl2 implements PersonService {
private String name;
private PersonDao personDao;
public PersonServiceImpl2(String name, PersonDao personDao) {
this.name = name;
this.personDao = personDao;
}
} //可以没有setter方法
xml配置文件
<bean id="personDao" class="com.spring.dao.impl.PersonDaoImpl"></bean>
<bean id="personService2" class="com.spring.service.impl.PersonServiceImpl2">
<constructor-arg index="0" value="dyy"></constructor-arg>
<constructor-arg index="1" type="com.spring.dao.PersonDao" ref="personDao"></constructor-arg>
</bean>
注意:index属性,type属性, value属性,ref属性的使用。
6.spring中使用注解(annotation)的方式装配属性
step1.修改配置文件:
加入新的命名空间:xmlns:context="http://www.springframework.org/schema/context"
加入新的约束文件:http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd"
加入注册处理器配置:<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
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<context:annotation-config/>
</beans>
step2.添加需要的jar包:
lib\j2ee/common-annotations.jar
@Autowire:默认按类型装配。可以和@Qualifier一起使用按名称装配,还可以设置required属性是否可以为null。
@Resource:默认按名称装配,当找不到对应的名称时,就按类型装配。
可以使用一个name属性标识名称,若没找到name属性的bean,默认取字段的名称作为name的值。
都可以用在字段上和setter方法上。
7.spring中的属性的自动装配(使用autowire属性)
<bean id="" class="" autowire="default"></bean>
autowire的取值和含义: byType:按类型装配,可以根据属性的类型,在容器中寻找跟该类型匹配的bean。
byName:按名称装配,可以根据属性的名称,在容器中寻找跟该属性名相同的bean。
bonstructor:与byType类似,用于构造器参数。
autodetect:通过自省机制(introspection),来决定使用constructor还是byType方式。
若发现默认构造器,那么将使用byType方式。
注意:必须和@Autowire标注配合使用。不推荐使用,可能发生一些不期望的结果。
8.spring中自动扫描和管理bean
在使用annotation的环境下注册处理器:<context:component-scan base-package="要扫描的包名" />
在class上面配置不同的标注:
@Service(idName) 标注业务层组件(如Service层)
@Controller(idName) 标注控制层组件(如struts中的Action上)
@Repository(idName) 标注数据访问组件(如 Dao层)
@Component 泛指组件,当组件不好归类的时候,使用这个标注进行标注。
目前,这四个标注没有特别的区别。功能一样。
访问自动管理的bean:
使用getBean(idName/className)时,如果没有指定idName,那么就是使用默认的ClassName首字母小写。
设置bean的范围:
在类标注后面接着使用@Scope标注,
@Scope( prototype/singleton(默认))。
设置初始化/摧毁方法:
在标注类的初始化方法上使用@PostConstruct,不是spring自己的注解,是ejb3的注解
@PostConstruct
public void init(){}
在标注类的摧毁方法上使用@PreDestroy标注
@PreDestroy
public viod destroy(){}
9.spring中使用AOP
代理模式:proxy我们不直接调运目标对象,我们直接调运代理对象,让代理对象去调运目标对象。
我们就可以在调运代理对象的时候做一些权限处理。
方式1:使用jdk提供的代理对象(代理对象需要实现InvocationHandler接口,目标对象必须实现其他接口)
public class JDKProxyFactory implements InvocationHandler {
private Object targetObject;//需要调运的目标对象
/**
* 返回创建好的代理对象
* @param targetObject
* @return
*/
public Object createProxyInstance(Object targetObject) {
this.targetObject = targetObject;
//loader - 定义代理类的类加载器
//interfaces - 代理类要实现的接口列表
//h - 指派方法调用的调用处理程序 (指定调运那个类的invoke方法)
return Proxy.newProxyInstance(this.targetObject.getClass()
.getClassLoader(),
this.targetObject.getClass().getInterfaces(), this);
//参数是this,就表示调运自己的invoke的方法。
}
/*
* 当代理对象的方法被调运时,就会执行回调函数invoke方法,让这个回调函数再去执行目标代码的指定方法,
* 并且会将代理对象接收到的参数传递给目标代码。这是一个回调函数。
* 注意:method args 都是由调运代理对象后产生的。所以是确定的。
* 还可以在这个回调函数中做一些手脚,比如限制调运或者其他。
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
PersonServiceImpl bean = (PersonServiceImpl) this.targetObject;
Object result = null;
if (bean.getUser() != null) {
result = method.invoke(targetObject, args);
}
return result;
}
}
注意:目标对象必须实现接口。因为需要得到接口的所有方法,然后进行调运接口的所有方法。
方式2:使用cglib提供的代理对象(代理对象需要实现MethodInterceptor接口,目标对象不需要实现接口)
//导包:cglib-nodep-2.2.3.jar
public class CGlibProxyFactory implements MethodInterceptor {
private Object targetObject;
/**
* 注意,生成的代理对象其实就是目标对象的子类。
* @param targetObject
* @return
*/
public Object createProxyInstance(Object targetObject) {
this.targetObject = targetObject;
Enhancer enhancer = new Enhancer();// 用于生成代理对象
enhancer.setSuperclass(this.targetObject.getClass());// 设置代理对象的父类
enhancer.setCallback(this);// 设置回调函数对象为本生
return enhancer.create();// 生成代理对象
}
/**
* 回调函数
*/
@Override
public Object intercept(Object proxy, Method method, Object[] args,
MethodProxy methodProxy) throws Throwable {
PersonServiceImpl bean = (PersonServiceImpl) this.targetObject;
Object result = null;
if (bean.getUser() != null) {
return result = methodProxy.invoke(bean, args);
}
return null;
}
}
注意:目标对象不须实现接口。因为生成的代理对象时目标对象的子类。
使用spring框架中的AOP(使用注解的方法)
step1.修改配置文件
加入新的命名空间:xmlns:aop="http://www.springframework.org/schema/aop"
加入新的约束文件:http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
加入注册处理器配置:<aop:aspectj-autoproxy/>
完整的配置文件:
<?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"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
<aop:aspectj-autoproxy/>
</beans>
step2.导入jar文件
aspectjrt.jar aspectjweaver.jar cglib-nodep-2.2.3.jar
step3.开发AOP(xml)
配置aop;
<bean id="interceptorXML" class="com.spring.aop.InterceptorXML" />
<bean id="personServiceImpl" class="com.spring.service.impl.PersonServiceImpl"></bean>
<aop:config>
<aop:aspect id="asp" ref="interceptorXML">
<aop:pointcut id="aspcut"
expression="execution(* com.spring.service.impl.PersonServiceImpl.*(..))" />
<aop:before method="before" pointcut-ref="aspcut" />
<aop:after method="after" pointcut-ref="aspcut" />
<aop:after-returning method="afterReturning"
pointcut-ref="aspcut" />
<aop:after-throwing method="afterThrowing"
pointcut-ref="aspcut" />
<aop:around method="around" pointcut-ref="aspcut" />
</aop:aspect>
</aop:config>
拦截器代码:
public class InterceptorXML {
public void before(){
System.out.println("前置通知");
}
public void afterReturning(){
System.out.println("后置通知");
}
public void afterThrowing(){
System.out.println("例外通知");
}
public void after(){
System.out.println("最终通知");
}
public Object around(ProceedingJoinPoint pjp) throws Throwable{
System.out.println("环绕通知");
Object result = pjp.proceed();
return result;
}
}
step3.开发AOP(annotation)
配置aop:
<aop:aspectj-autoproxy />
<bean id="interceptorAnnotation" class="com.spring.aop.InterceptorAnnotation"></bean>
<bean id="personServiceImpl" class="com.spring.service.impl.PersonServiceImpl"></bean>
拦截器代码:
@Aspect
public class InterceptorAnnotation {
@Pointcut("execution (* com.spring.service.impl.PersonServiceImpl.*(..))")
private void anyMethod(){}//声明一个切入点
@Before("anyMenthod()")
public void before(){
System.out.println("前置通知");
}
@AfterReturning(pointcut="anyMenthod()")
public void afterReturning(){
System.out.println("后置通知");
}
@AfterThrowing(pointcut="anyMenthod()")
public void afterThrowing(){
System.out.println("例外通知");
}
@After("anyMenthod()")
public void after(){
System.out.println("最终通知");
}
@Around("anyMenthod()")
public Object around(ProceedingJoinPoint pjp) throws Throwable{
System.out.println("环绕通知");
Object result = pjp.proceed();
return result;
}
}
spring详解
猜你喜欢
转载自dyygusi.iteye.com/blog/2048176
今日推荐
周排行