1.Spring的IOC容器的关键点
(1)必须将被管理的对象定义到Spring配置文件中。
(2)必须定义构造函数或setter方法,让Spring将对象注入进来。
(3)Spring默认的scope配置为singleton(单例模式),默认在容器启动时
就对bean进行实例化,可配置lazy-init=”true”,则获取Bean时才会初始化。
如果改为prototype,则每次会创建一个新实例,可避免线程安全问题。
(4)Spring的自动装配有二种:
一种是根据名称自动装配,例setXXX(),XXX需与Spring中配置的ID一致,
在头部文件中定义default-autowire=”byName”,
另一种是根据类型自动装配,Spring中配置的Id可随意定义,可不与setXXX()中的XXX一致,
会自动查找相应的Class类型,在头部文件中定义default-autowire=”byType”
2.Spring相关概念
(1)IOC(控制反转):应用本身不负责依赖对象的创建及维护,依赖对象的创建及维护是由外部容器实现的。
(2)DI(依赖注入):在运行期,由外部容器动态地将依赖对象注入到组件中。
(3)AOP(面向切面编程):通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能
3.Spring配置,如果XML文件不会自动提示,可配置相关的XSD文件。
(1)构造函数配置
- 例:<bean id="" class="">
- <constructor-arg ref=""></constructor-arg>
- </bean>
(2)set方法的配置
- 例:<bean id="jdbcTemplate" class=" ">
- <property name="dataSource" ref="dataSource"/>
- </bean>
(3)init-method=”方法名”,可指定bean实例化时初始化调用的方法。
Destroy-method=”方法名”,在spring容器关闭时,bean销毁时调用的方法。
(4)Spring集合类型的装配
Set类型:
- <property>
- <set>
- <value>1</value>
- <value>2</value>
- </set>
- </property>
List类型:
- <list>
- <value>1</value>
- <value>2</value>
- </list>
Properties类型:
- <props>
- <prop key="key1">value1</prop>
- <prop key="key2">value2</prop>
- </props>
Map类型:
- <map>
- <entry key="key1" value="value1"></entry>
- <entry key="key2" value="value2"></entry>
- </map>
4.Spring的加载
- BeanFactory factory = new ClassPathXmlApplicationContext
- ("applicationContext.xml");
- DataSource ds = (DataSource) factory.getBean("dataSource");
得到在Web.xml文件中配置的Spring实例
- WebApplicationContext ctx = WebApplicationContextUtils
- .getWebApplicationContext(sx);
- UserManager userManager = (UserManager)ctx.getBean("userManager");
5.Sping AOP
(1)静态代理,创建一个代理类,实现具体操作的接口,在每个实现方法前调用代理类的代理方法。
- 例:public class UserManagerProxy implements UserManager{
- private UserManager userManager;
- public UserManagerProxy(UserManager userManager){
- this.userManager = userManager;
- }
- public void addUser(User user){
- //可在此添加具体的代理方法,如checkSecurity()等
- this.userManager.addUser(user);
- }
- }
(2)动态代理
- 例: public class SecurityHandler implements InvocationHandler{
- private Object targetObject;
- public Object newProxy(Object targetObject){
- this.targetObject = targetObject;
- return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
- targetObject.getClass().getInterfaces(),this);
- }
- public Object invoke(Object proxy, Method method, Object[] args)
- throws Throwable {
- // 可在此添加具体代理操作方法
- Object ret = method.invoke(this.targetObject, args);
- return ret;
- }
- }
- //客户端调用代码:
- 例:
- SecurityHandler handler = new SecurityHandler();
- UserManager userManager = (UserManager)handler
- .newProxy(new UserManagerImpl);
- usermanager.deleteUser(userId);
(3)Cglib代理,用来代理没有实现接口的类
例:
- public class MyClass {
- public void myMethod(){
- System.out.println("MyClass.myMethod()");
- }
- }
- public class CglibTest {
- public static void main(String args[]){
- Enhancer enhancer = new Enhancer();
- enhancer.setSuperclass(MyClass.class);
- enhancer.setCallback( new MethodInterceptorImpl() );
- MyClass my = (MyClass)enhancer.create();
- my.myMethod();
- }
- }
- class MethodInterceptorImpl implements MethodInterceptor {
- public Object intercept(Object obj,
- Method method,
- Object[] args,
- MethodProxy proxy)
- throws Throwable {
- System.out.println(method);
- // 可在此添加相关代理操作方法
- return proxy.invokeSuper(obj, args);
- }
- }
6.Spring Aop应用
Aop可执行前置通知,后置通知,例外通知,最终通知。
(1)相关概念
Aspect(切面):横切性关注点的抽象即为切面。
JointPoint(连接点):指那些被拦截到的点(spring中指方法)
PointCut(切入点):指要对那些JointPoint进行拦截的定义。
Advice(通知):指环绕到JointPoint之后所要做的事情(前置,后置…)
Target(目标对象):指代理的目标对象
Weave(织入):指将aspects应用到target对象并导致proxy对象创建的过程称为织入。
Introduction(引入):在不修改类代码的前提下,在运行期动态为类添加方法或字段。
(2)基于注解方式的应用
在xml中配置 <aop:aspectj-autoproxy />.
2.1在类上添加@Aspect,代表切面
2.2在方法上添加@PointCut(“execution(* com.test.service..*(..))”)
PointCut代表切入点,指对哪些业务方法进行拦截定义。
Execution指执行方法时调用。
第一个*代表任意返回类型。
Com.test.service..*指com.test.service包底下(包含子包)的所有类。
(..)指代表任意参数值。
2.3 @Before(“myMethod()”),前置通知,myMethod指切入点定义的方法。
2.4 @AfterReturning(“myMethod()”),后置通知
2.5 @After(“myMethod()”),最终通知
2.6 @AfterThrowing(“myMethod()”),例外通知
2.7 @Around(“myMethod()”),环绕通知
如果通知中需接收参数,可用
@Before(“myMethod() && args(name)”)
对应public void myMethod(String name){}
如果需接收返回值,可用
@AfterReturning(pointCut=”myMethod()” ,returning=”result”)
对应public void myMethod(String result){},将返回结果以参数值传入。
(3) 基于XML方式配置AOP
例:
- <aop:aspectj-autoproxy />
- <aop:config>
- <aop:aspect id="aspectId" ref="aspectBean">
- <aop:pointcut id="myCut" expression="execution(* com.test.service..*(..))"/>
- <aop:before pointcut-ref="myCut" method="doAccessCheck"/>
- </aop:aspect>
- </aop:config>>
7.Spring 事务应用
(1)使用注解方式配置事务
1.1首先声明事务的命名空间 xmlns:tx="http://www.springframework.org/schema/tx"
1.2 配置事务管理器
- <bean id="transactionManager"
- class="org.springframework.orm.hibernate3.HibernateTransactionManager">
- <property name="sessionFactory" ref="sessionFactory" />
- </bean>
1.3 定义配置项,处理注解
- <tx:annotation-driven transaction-manager="transactionManager"
- proxy-target-class="true" />
1.4 为类添加注解,声明事务
@Transactional(在类上面定义,每个业务方法会启动一个事务)
(2)在Spring开启的事务中,默认情况下,如果碰到运行期异常(RuntimeException),则会回滚事务,
如果是检查异常(Exception),则默认不回滚事务。
可修改默认配置,在方法上添加注解
例:@Transactional(rollbackFor = Exception.class),则检查异常也会回滚事务,
如果为noRollbackFor,则不回滚事务。
(3)事务的相关传播特性
3.1 @Transactional(propagation=Propagation.NOT_SUPPORTED),则不开启事务。
3.2 REQUIRED,业务方法在一个事务中运行。(默认)
3.3 REQUIRES_NEW 业务方法总会发起一个新事务。
3.4 NESTED 使用一个单独的事务,拥有多个可以回滚的保存点。
(4)事务的隔离级别,依赖于底层的数据库
@Transactional(isolation=””)
4.1 Isolation.READ_COMMITTED,读已提交的数据。
4.2 READ_UNCOMMITTED,读未提交的数据。
4.3 REPEATABLE_READ,可重复读
4.4 SERIALIZABLE,串行化
(5)基于XML配置事务
- <aop:config>
- <aop:pointcut id="transactionPointCut"
- expression="execution(* com.service..*.*(..))" />
- <aop:advisor advice-ref="txAdvice" pointcut-ref="transactionPointCut"/>
- </aop:config>
- <tx:advice id="txAdvice" transaction-manager="txManager">
- <tx:attributes>
- <tx:method name="get *" read-only="true" propagation="NOT_SUPPORTED"/>
- <tx:method name="*"/>
- </tx:attributes>
- </tx:advice>
8.Spring注解
采用Spring注解需导入相应的命名空间,并配置:
<context:annotation-config />
(1)@Autowired,默认按类型装配
例:
@Autowired
private BiJdbcTemplate biJdbcTemplate;
将BiJdbcTemplate类型的对象注入到它所属的类实例中。
(2)@Resource,默认按名称装配,当找不到名称装配再按类型匹配。
例:@Resource
Private Person person;
将person对象注入到它所属的类实例中。
如果指定(name=”person”),则只能按名称进行匹配。
(3)自动扫描组件纳入Spring进行管理
- <context:component-scan base-package="com.rosy" />
可在类路径下寻找标注了@Componet(组件,组件不好归类时使用),@Service(业务层),
@Controller(控制层),@Repository(Dao层)的组件纳入Spring进行管理,以上注解可以替换使用,
起标注作用而已。默认的类的名称为类的名称首字母变为小写,也可自己手动指定名称,
例:@Service(“personService”);
(4)@PostConstruct,在方法上使用,可用来类实例化时初始化方法,对应init-method配置。
(5)@PreDestroy,在方法上使用,可用来类实例销毁时调用,对应destory-method配置。
9.使用Spring解决web乱码问题
在web.xml文件中配置,例:
- <filter>
- <filter-name>encodingFilter</filter-name>
- <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
- <init-param>
- <param-name>encoding</param-name>
- <param-value>UTF-8</param-value>
- </init-param>
- <init-param>
- <param-name>forceEncoding</param-name>
- <param-value>true</param-value>
- </init-param>
- </filter>
- <filter-mapping>
- <filter-name>encodingFilter</filter-name>
- <url-pattern>/*</url-pattern>
- <dispatcher>REQUEST</dispatcher>
- <dispatcher>FORWARD</dispatcher>
- </filter-mapping>