1.spring使用AOP(面向切面编程),先得引入jar包,再定义命名空间
2.service层:面向接口,提供不同的实现方法
3.AOP只能切IOC容器里边的bean,这是限制。
4.假如bean是个数组,如何注入参数?可以利用
<list></list>
5.工厂方式创建ioc容器的属性
<factory-bean><factory-method>
6.动态代理(系统利用回调函数生成)和静态代理(自己写)区别
动态代理:JVM利用回调函数、反射等机制生成代理类,不需要手动写。
静态代理:自己写
动态代理更有利于程序的扩展,不需要改变原来的代码。
下边距一个静态代理的例子。
接口Isubject
public interface Isubject {
void request();
}
/**
* 真实对象
*
*/
public class RealSubject implements Isubject{
public void request() {
System.out.println("真实对象的方法");
}
}
/**
* 静态代理对象
*
*/
public class ProxySubject implements Isubject{
private RealSubject re;
public ProxySubject(){
re = new RealSubject();//在代理类的构造方法中实例化"真实类"
}
public void request() {
System.out.println("之前");
re.request();//调用的将是"真实类的方法"
System.out.println("之后");
}
}
测试类
public class Test {
public static void main(String[] args) {
Isubject pro = new ProxySubject();//父类对象指向子类引用
pro.request();
}
}
结果为:
之前
真实对象的方法
之后
7.使用spring的第一步永远是先建立IOC容器,如下
ApplicationContext ac = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"});
//构建ioc容器,ioc容器默认是单例,并且是预加载,也可以设为多例,工厂模式
8.annotation方式也可配置AOP,但不推荐,还是用xml多一些。使用注解配置比较繁琐。
9.openSessionView最好和hibernateTemplate结合起来使用。
10.spring注解的用法。如一个action中
@Component //把普通vo中的实体类实例化到spring容器中,相当于<bean id="" class="" />
@Scope("prototype")
//@Scope指定bean的作用域,默认作用域是singleton
//若需要的bean是一个单例,则定义@Scope("singleton");若每次都new一个新的,则用@Scope("prototype")
public class OrganizationAction {
@Resource
//按照配置(name或type)给属性注入实例,默认按name注入,spring将@Resource注解的name属性解析为bean的名字
//@Resource(name)一般写到set方法上边。
private OrganizationService organizationService;
private List<Organization> list;
private Integer pid;
//其余略
}
@Resource的用法
@Resource(name="ud")
private UserDao userDao;
//直接找name为ud的bean
@Resource
private UserDao userDao;
//直接找name为userDao的bean,如果找到这个bean就注入;如果没有name=userDao的bean,
//则找接口UserDao下的唯一实现类。如果接口UserDao下有多个实现类,则抛出异常。
<bean>的<scope>属性管理作用域,默认为singleton,表示一个bean类型对应一个对象。也可为prototype,表示一个bean类型对应多个对象。每次从容器中取到的对象都是新对象。
11.在spring的配置文件中,如
<bean id="userDao" class="com.bjsxt.dao.UserDao">
这里应注意,若UserDao里有属性,则必须
①有相应的get/set方法
②有无参数的构造器
12.ioc 控制翻转,意味着将设计好的类交给系统去控制,而不是在类的内部控制。将对象的创建和获取提取到外部,由外部容器提供需要的组件。注意:
①由控制器控制程序之间的关系,而不是由应用程序直接控制
②由于控制权由应用程序转向了容器,所以叫反转。
ioc/di最广泛的实现方式是setter注入(设值注入),必须注意:
①属性必须有对应的set方法(注意,只要求有set方法)
②配置文件内容使用一下类似的
<bean id="userDao" class="com.bjsxt.dao.UserDao"></bean>
<bean id="userServicce" class="com.bjsxt.service.UserService">
<property name="userDao" ref="userDao"></property>
</bean>
也可通过注解注入,不过需要修改配置文件。如:
@Resource(name="userDao") //若不指定name,默认就是属性名,一般不需要单独指定
public class UserServiceImpl implements UserService{
@Resource
private UserDao userDao; //相当于 = new UserDaoImpl()
}
13.spring的核心就是ioc和aop。ioc就是控制反转,由容器控制程序之间的依赖关系,而非传统实现中由程序代码直接操控。aop主要应用到事务的处理当中。在以往的事务处理中,都由try/catch来处理异常。而在spring中,由于它封装了所有对事务处理的功能,集成了TransactionTemplate。hibernate中对事务处理是通过SessionFactory创建和维护session来完成。
spring也对SessionFactory进行了整合,这样就不需要每次对数据操作都要先获得session实例来启动/提交/回滚事务和try/catch操作。
14.tx为“事务”transiaction的缩写。
15.对于session的作用域问题,有时会需要取session里的值,但session已关闭而导致出错。这时可以用OpenSessionInViewFilter处理,OpenSessionInViewFilter是spring为hibernate提供的一个类,主要作用是在发起一个页面请求时打开hibernate的session,请求结束后再关闭这个session,相当于扩大了session的作用域。写好后要配到web.xml中。如
public class OpenSessionInViewFilter implements Filter{//实现Filter接口,并重写三个方法
public void init(FilterConfig filterConfig) throws ServletException {
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
Session session = HiberUtil.getSession();
HiberUtil.threadLocal.set(session);
chain.doFilter(request, response);
session.close();
HiberUtil.threadLocal.remove();
}
public void destroy() {
}
}
而HiberUtil里的threadLocal为
public class HiberUtil {
private static SessionFactory factory;
public static ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();
static{
Configuration conf = new AnnotationConfiguration().configure();
factory = conf.buildSessionFactory();
}
public static Session getSession(){
Session session = threadLocal.get();
if(session==null){
session = factory.openSession();//开启新的session
}
return session;
}
public static void main(String[] args) {
// System.out.println(factory.openSession()==null);
System.out.println(HiberUtil.getSession()==null);
//这两个方法的本质是一样的,都是为了开启session。即可完成建表
}
}
ThreadLocal并不是一个Thread,而是Thread的局部变量。ThreadLocal使得各线程能够保持各自独立的一个对象,是通过每个线程中的new 对象的操作来创建的对象,每个线程创建一个,不是什么对象的拷贝或副本。通过ThreadLocal.set()将这个新创建的对象的引用保存到各线程的map当中。执行ThreadLocal.get()时,各线程从自己的map中取出放进去的对象。
16.spring中,使用的设计模式包括:
工厂模式,就是用SessionFactory创建、管理session;单例模式,创建SessionFactory类就是单例;代理模式,就是动态代理和懒加载。