spring学习总结

1.如何使用spring

必须的JAVA文件

a) Spring.jar

b) Commons-logging.jar

如果使用切面编程,还需要下列文件:

c) aspectj/Aspectjweaver.jar

d) aspectj/Aspectjrt.jar

e) Cjlib/cjlib-nodep-x.x.jar

如果使用jsr-250的注解时需要添加下列文件:

f) /j2ee/Common-annotations.jar

Spring包文件结构:

Spring的配置文件:

1.名字可以随意取

2.可以有多个配置文件(可用数组方式)

实现软件解藕,采用接口的编程方式。

配置文件的元素及属性

<bean id="唯一名字,不能包含特殊字符" name="也代表名字,但是可经有特殊字符" init-method="指定初始化方法" destory-method="指定bean被销毁的时候执行的方法">

Bean是什么时候被销毁的呢?默认是在容器停止时,才会销毁。但同样我们可以采用这样一个抽象类来正常关闭:

AbstractApplicationContext ctx = ;

Ctx.close;可以正常关闭。

<!-- 普遍方式 -->

<bean id="personService" class="cn.itcast.spring.service.impl.PersonServiceBean" />

<!-- 工厂静态方法模式 -->

<bean id="personService2" class="cn.itcast.spring.service.impl.PersonServiceBeanFactory"

factory-method="createPersonServiceBean" />

<!-- 工厂方法 -->

<bean id="beanFactory" class="cn.itcast.spring.service.impl.PersonServiceBeanFactory"/>

<bean id="personService3" factory-bean="beanFactory" factory-method="createPersonServiceBean2"/>

Bean 的使用域:

默认为单例模式。默认是在容器初绍化时初始化。但可以通过lazy-init="true"进行更改。但在实际应用中大多采用的通过不采用。

DI(注入)

注入的方式:

1.set方法 bean可以被我个ref使用

2.构造方法

3.内部bean 只能提供一个服务

如何为基本类型注入值呢?直接:

<property name="属性名" value="值" />

注入集合,properties等 例子如下:

<bean id="personService" class="cn.itcast.spring.service.impl.PersonServiceBean" >

<property name="personDao" ref="personDao"/>

<property name="id" value="1"/>

<property name="name" value="pingping"/>

<property name="set">

<set>

<value>1</value>

<value>2</value>

<value>3</value>

</set>

</property>

<property name="list">

<list>

<value>11</value>

<value>22</value>

<value>33</value>

</list>

</property>

<property name="prop">

<props>

<prop key="a">1</prop>

<prop key="b">2</prop>

<prop key="c">3</prop>

</props>

</property>

<property name="map">

<map>

<entry key="a" value="a" />

<entry key="b" value="a" />

<entry key="c" value="a" />

</map>

</property>

</bean>

注入-手工装配

1.以上是手工装配的方式的一种:在xml文件中进行注入。但是在实际的开发过程中bean有成百上千,所以配置文件可能非常的多。我们就可以采用下一种方式:注解

2.但是还可以采用注解的方式进行注入。

a) 首先添加

<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

           www.springframework.org/schema/context

           http://www.springframework.org/schema/context/spring-context-2.5.xsd">

           

<!-- 采用注解的方式 -->

<context:annotation-config/>

</beans>

@Autowired默认按类型进行装配。这是spring提供的,默认按类型进行装配。可以手动设置成按名称注入,加入:@Autowired  @Qualifier("personDao")。

@Resource默认按名称进行装配,如果按名字找不到,在按类型。其有一个name属性。如果没有指定,就按类中指定的名字,进行查找。建议使用。这个即可用在属性上,也可以用到set方法上。

传智播客注解原理:

1.定义一个注解,该注解可以放在属性和方法上。定义一个属性name。

2.有一个处理器。

a) 根据方法:

1.循环所有的bean对象

2.获取每一个bean对象

3.如果存在,获得属性

4.循环属性,获得其“写”方法。判断该方法是否存在注解是存在指定的注解。

5.判断该注解是是否有name属性。如果有,取出name属性。根据name属性查找 装bean的集合中的 容器是否有该name对应的对象,有则赋值。如果没有,则取得属性的名称,用属性名称去集合中取bean, 赋值。如果都没有寻找到,就按类型去寻找。循环所有的bean判断bean的类型是否和name所对应的 bean的类型是否匹配,如果有,则赋值。

B).根据属性

同上四五步,不去找写方法,而是直接用属性去找到注解。

注入-自动装配

在bean 中设置一个属性:autowire="行为"

不建议使用(老师推荐)

通过classPath自动把组件扫描进spring容器中进行管理:

<context:component-scan base-package="扫描指定路径" />

他是怎么知道一个类是否要交给容器管理呢?这里用到了注解。在类之前组解

1.@Service 服务层 service

2.@Controller 控制层action

3.@Repository  数据访问层(dao)

4.@component 泛指组件。

目前他们的作用是一样的。但是他们是怎么知道受管理时的名字呢?相当于:<bean name=""/>,所以,他们指供了设置名字:@Service("名字"),如果没有设置时,就是类的简单名称,将第一个字符小写。当然,也是可以设置作用域的 @scope("prototype");每调用一次就产生一个新对象。指定初始化方法:在一个方法上加@PostConstruct。也可以设置销毁方法!
AOP

1.可以采用Proxy.newInstance方法来实现。Java提供

2.Cglib来实现

根据以上的理解,我猜测spring AOP 的实现的原理,应该不是采用以上的两种方式吧!

AOP概念:

采用spring AOP 进行面向切面编程:
1.采用注解的方式

定义一个切面(比较全面,以后利于查阅):定义之后,在xml中加入:<aop:aspectj-autoproxy/>,就不用理他了,自动完成。切点定义了,用在那些的地方,而在定义具体的通知表示要做的事情,此时还可以设置范围,满足条件下才可以执行。

@Aspect

public class MyInterceptor {

// service下所有包,所有类,所有方法,任何返回类型

@Pointcut("execution (* cn.itcast.aop.service.impl.PersonServiceBean.*(..))")

private void anyMethod() {}//声明一个切入点

@Before("anyMethod() && args(name)")// 可以在这里添加&&,来匹配其它的条件。比如:args(name),这儿的名字要和下面方法的名字一致.相当于要执行前面的条件的同时,同时滶参数只有一个,且为string

public void doAccessCheck(String name){

System.out.println("前置通知");

}

//同样也可以得到访求的返回值,以及例外(异常)等。

@AfterReturning("anyMethod()")

public void doAfterReturn(){

System.out.println("后置通知");

}

@After("anyMethod()")

public void doAfter(){

System.out.println("最终通知");

}

@AfterThrowing(("anyMethod()"))

public void doThrow(){

System.out.println("例外通知");

}

@Around("anyMethod()")

public Object doBaseProfiling(ProceedingJoinPoint pjp) throws Throwable{

//必须执行这个方法,如果不执行,业务bean中的方法是不会执行的.如果后面还有切面,先执行后面的

Object result = pjp.proceed();

System.out.println("环绕通知");

return result;

}

}
2.采用xml方式

<bean id="myInterceptor" class="cn.itcast.aop.service.MyInterceptor" />

<bean id="personService" class="cn.itcast.aop.service.impl.PersonServiceBean" />

<aop:config>

<aop:aspect id="asp" ref="myInterceptor">

<aop:pointcut

expression="execution(* cn.itcast.aop.service.impl.PersonServiceBean.*(..))"

id="mycut" />

<aop:before pointcut-ref="mycut" method="doAccessCheck"  />

<aop:around method="doBaseProfiling" pointcut-ref="mycut"/>

</aop:aspect>

</aop:config>

特别需要注意的是:execution(* cn.itcast.aop.service.impl.PersonServiceBean.*(..)) 大有文章,要对什么方法拦截,完全在这儿控制。

问题:spring AOP 可不可以在执行一个java本身的类进行拦截呢?

SPRING+JDBC

1.配置数据源:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">

<property name="driverClassName" value="com.mysql.jdbc.Driver"/>

<property name="url" value="jdbc:mysql:///test"/>

<property name="username" value="root"/>

<property name="password" value="123456"/>

<!-- 连接沲初始值 -->

<property name="initialSize" value="1"/>

<!-- 连接沲最大值 -->

<property name="maxActive" value="500"/>

<property name="maxIdle" value="2"/>

<property name="minIdle" value="1"/>

</bean>

2.采用注解方式配置事务

a) 事务管理器

<!-- 事务管理器 -->

<bean id="txManager"

class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

<property name="dataSource" ref="dataSource" />

</bean>

<!-- 使用注解时要这样 -->

<tx:annotation-driven transaction-manager="txManager" />

<bean id="personService" class="cn.itcast.service.PersonServiceBean">

<property name="dataSource" ref="dataSource" />

</bean>

该bean要类头要要添加 @Transactional 

把数据库的连接信息搞到另外一个文件中。

<context:property-placeholder location="classpath:jdbc.properties" />

3.Spring事务

a) Spring 开起事务之后,默认是运行期意外//unchecked会回滚。RunTimeException

b) 如果是Excption这种异常时,不会回滚。Checked不会

c) 如果我们也想要他回滚进,我们可以在方法加入:

i. @Transactional(rollbackFor=Exception.class)

d) 有一些方法不需要事务管理。不需要时,我们要怎么做呢?默认开启了事务。因为这样会影响性能。同工同酬我们可以这样做:@Transactional(propagation=Propagation.NOT_SUPPORTED)

e) 事务传播行为:

 

问题:如何开起一个新的事务?

数据库的隔离级别:

Spring的团队,建议采用注解配置。而现在很多公司采用xml。因为注解的方式,配置每一个方法比较容易,而采用xml的方式则,配置比较臃肿。



你可能感兴趣的:(spring学习总结)