Spring笔记整理

IOC概念解析

ioc简单代码示例
IMessage.java

    public interface IMessage {
        public abstract String getMessage();
        }

Message.java

public class Message implements IMessage {
    @Override
    public String getMessage() {
    return "Hello World!";
    }
}

NewMessage.java

public class NewMessage implements IMessage {
        @Override
        public String getMessage() {
            return "Hello Every One!";
        }
    }

message.properties

    1=com.alyshen.spring.Message
    2=com.alyshen.spring.NewMessage

MessageFactory.java

    public class MessageFactory {
    
        public static IMessage create(String key) {
    
    //      if ("1".equals(key)) {
    //          //工厂还是依赖这个类
    //          return new Message();
    //      }
    //      
            // 使用资源文件
            ResourceBundle bundle = ResourceBundle.getBundle("message");
            String _class = bundle.getString(key);
            try {
                return (IMessage) Class.forName(_class).newInstance();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
            return null;
        }
    }

MainClass.java

    public class MainClass {
    
        public static void main(String[] args) {
            // 这个类强依赖Message这个类
            // Message msg = new Message();
            
            // 我们不想看到Message这个具体的产品
            // IMessage msg = new Message();
    
            IMessage msg = MessageFactory.create("1");
            System.out.println(msg.getMessage());
    
            msg = MessageFactory.create("2");
            System.out.println(msg.getMessage());
        }
    }

Spring环境配置及IOC工厂应用

用到的包以及文件

包以文件 说明
applicationContext.xml Spring配置文件
spring-context-3.2.0.M1.jar 主要提供bean工厂的实现类,工厂就在里头,但是接口在spring-beans-3.2.0.M1.jar里头
spring-beans-3.2.0.M1.jar bean工厂在里头
spring-core-3.2.0.M1.jar Spring核心包
spring-expression-3.2.0.M1.jar 支持spring表达式的
spring-asm-3.2.0.M1.jar 动态生成一些类的(动态生成字节码的类)
commons-logging-1.1.1.jar 依赖包(公共日志包)

spring配置文件:applicationContext.xml




    
    

使用spring的bean工厂

public class MainClass {
    public static void main(String[] args) {
    // 使用spring 的bean工厂
    BeanFactory factory = new ClassPathXmlApplicationContext(
    "applicationContext.xml");
    // 使用通配符
    // BeanFactory factory = new ClassPathXmlApplicationContext("app*.xml");

    IMessage msg = (IMessage) factory.getBean("msg1");
    System.out.println(msg.getMessage());

    // 我们自己的bean工厂
    msg = MessageFactory.create("2");
    System.out.println(msg.getMessage());
    }
}

Spring依赖注入的基本方法

set方法注入示例
UserManager.java

public class UserManager {
    // 依赖set方法注入
    private String driverCalss;
    private String url;
    private String username;
    private String password;

    public void addUser() {
        System.out.println(this.toString());
        System.out.println("用户管理_添加用户!");
    }

    public void setDriverCalss(String driverCalss) {
        this.driverCalss = driverCalss;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    @Override
    public String toString() {
        return "UserManager [driverCalss=" + driverCalss + ", url=" + url
        + ", username=" + username + ", password=" + password + "]";
    }
}

UserAction.java

public class UserAction {
    private UserManager manager = null;

    public void setManager(UserManager manager) {
    System.out.println("调用属性manager的set方法注入!");
    this.manager = manager;
    }

    public String execute() {
    this.manager.addUser();
    return "success";
    }
}

spring配置文件:applicationContext.xml




    
        
        
        

        
        
        
        
        
        
    

MainClass.java

    public static void main(String[] args) {
    
        // 使用spring 的bean工厂
        BeanFactory factory = new ClassPathXmlApplicationContext(
                "applicationContext.xml");
        // BeanFactory factory = new ClassPathXmlApplicationContext("app*.xml");
    
        UserAction ua = (UserAction) factory.getBean("userAction");
        System.out.println(ua.execute());
    }

Scope属性和BeanFactoryAware接口

UserManager.java

public class UserManager {

    // 依赖set方法注入
    private String driverCalss;
    private String url;
    private String username;
    private String password;

    public void addUser() {
        System.out.println("用户管理_添加用户!");
    }
    //各种set及get方法
    ……
}

UserAction.java

/**
* 实现接口BeanFactoryAware
*/
public class UserAction implements BeanFactoryAware {
    private UserManager manager = null;

    public void setManager(UserManager manager) {
        // System.out.println("调用属性manager的set方法注入!");

        this.manager = manager;
    }

    public String execute() {
        // 每次调用这方法都重新创建bean工厂耗费资源,丧失性能
        // BeanFactory factory = 
        //      new ClassPathXmlApplicationContext("applicationcontext.xml");

        // 非要实现单列对象注入多例对象属性实现:
        // 重新为属性赋值
        manager = (UserManager) factory.getBean("userManager");

        System.out.println(manager);
        this.manager.addUser();
        return "success";
    }

    BeanFactory factory = null;

    @Override
    public void setBeanFactory(BeanFactory factory) throws BeansException {
        // TODO Auto-generated method stub
        this.factory = factory;
    }
}

applicationContext.xml




    
    
        
    

    
        
        
        
        
        
    

MainClass.java

public static void main(String[] args) {
    // UserAction userAction = new UserAction();
    // UserManager manager = new UserManager();
    // userAction.setManager(manager);

    // 使用spring 的bean工厂
    // BeanFactory factory = new ClassPathXmlApplicationContext("app*.xml");
    BeanFactory factory = new ClassPathXmlApplicationContext(
            "applicationcontext.xml");
    UserAction ua = (UserAction) factory.getBean("userAction");
    System.out.println(ua);
    System.out.println(ua.execute());
    
    ua = (UserAction) factory.getBean("userAction");
    System.out.println(ua);
    System.out.println(ua.execute());
    
    ua = (UserAction) factory.getBean("userAction");
    System.out.println(ua);
    System.out.println(ua.execute());
}

id_name_ref(bean、local、parent)等属性的用法
applicationContext.xml



    
        
        
    

MainClass.java

    /**
     * BeanFactory factory = new
     * ClassPathXmlApplicationContext("applicationContext02.xml");
     * 
     * 将factory作为父工厂(已不使用)
     * BeanFactory fay = new XmlBeanFactory( newClassPathResource(
     * "applicationContext.xml"), factory );
     */

set方法注入集合属性

UserAction.java

public class UserAction {

    public List list = null;
    public Set set = null;
    public Map map = null;
    public Properties props = null;

    public void setList(List list) {
        this.list = list;
    }

    public void setSet(Set set) {
        this.set = set;
    }

    public void setMap(Map map) {
        this.map = map;
    }

    public void setProps(Properties props) {
        this.props = props;
    }
}

applicationContext.xml



     
    

        
            
                zhaoliou
                
            
        

        
            
                dfdsf
                155.54
                1115
                true
            
        

        
            
                
                    user1
                
                
                    user2
                
            
        

        
            
                jdbc.mysql.Driver
                root
                654321
                jdbc:mysql://localhost:3306/mydb
            
        
    

    
  1. MainClass.java
public static void main(String[] args) {

    BeanFactory factory = new ClassPathXmlApplicationContext(
            "applicationContext.xml");
    UserAction userAction = (UserAction) factory.getBean("userAction");

    System.out.println("---------------list------------");

    for (Object o : userAction.list) {
        System.out.println(o);
    }

    System.out.println("---------------set------------");

    for (Object o : userAction.set) {
        System.out.println(o);
    }

    System.out.println("----------------map-----------");

    for (Iterator iter = userAction.map.entrySet().iterator(); iter
            .hasNext();) {
        System.out.println(iter.next());
    }

    for (Object key : userAction.map.keySet()) {
        System.out.println(key + ":" + userAction.map.get(key));
    }

    System.out.println("--------------props-------------");

    Properties prop = userAction.props;

    System.out.println(prop.get("driverClass"));
    System.out.println(prop.get("username"));
    System.out.println(prop.get("password"));
    System.out.println(prop.get("url"));
}

构造注入及注意事项

  1. A.java
public class A {
    private int id;
    private String username;
    private String password;
    private char sex;
    private Date birthday;

    @Override
    public String toString() {
        return "A [id=" + id + ", username=" + username + ", password="
                + password + ", sex=" + sex + ", birthday=" + birthday + "]";
    }

    public A(int id, String username, String password, char sex, Date birthday) {
        super();
        this.id = id;
        this.username = username;
        this.password = password;
        this.sex = sex;
        this.birthday = birthday;
    }
    //各种set、get方法
    ……
}
  1. applicationContext.xml



    
        
        
        
        
        
        
    
    
  1. MainClass.java
public static void main(String[] args) {
    BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");

    A a = (A) factory.getBean("a");
    System.out.println(a.toString());
}
  1. 注意事项

a) A.java

public class A {

    private B b;

    public void setB(B b) {
        this.b = b;
    }

    /**
     * 参数构造器
     */
    public A(B b) {
        super();
        this.b = b;
    }

    /**
     * 默认构造器
     */
    public A() {
        super();
    }
}

b) B.java

public class B {

    private A a;

    public void setA(A a) {
        this.a = a;
    }

    public B(A a) {
        super();
        this.a = a;
    }

    public B() {
        super();
    }
}

c) applicationContext.xml




    
        
        
    

    
        
        
    

自动注入及注意事项

  1. UserManager.java
public class UserManager {

public void addUser() {

    System.out.println("添加用户!");
}
}
  1. UserAction.java
public class UserAction {

    private UserManager manager = null;

    /**
     * 参数构造器注入
     */
    public UserAction(UserManager manager) {
        super();
        this.manager = manager;
    }

    /**
     * set方法注入
     */
    public void setManager(UserManager manager) {
        System.out.println("调用manager的set方法注入!");
        this.manager = manager;
    }

    public String execute() {
        System.out.println(manager);
        manager.addUser();
        return "success";
    }
}
  1. applicationContext.xml


    
    

    

    
  1. MainClass.java
public static void main(String[] args) {

    BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");

    UserAction ua = (UserAction) factory.getBean("userAction");
    System.out.println(ua);
    System.out.println(ua.execute());
}

通过注解注入

  1. applicationContext.xml


  
    
    

    

    
  1. UserAction.java
public class UserAction {

    @Resource
    private UserManager manager = null;
    //Set方法都省了
    //  @Resource
    //  public void setManager(UserManager manager) {
    //      System.out.println("调用manager的set方法注入!");
    //      this.manager = manager;
    //  }

    public String execute() {
        System.out.println(manager);
        this.manager.addUser();
        return "success";
    }
}

Spring自动扫描组件

  1. applicationContext.xml


    
    

    
    
  1. UserManager.java
@Repository("uManager")
public class UserManager {

    public void addUser() {

        System.out.println("用户管理执行添加User对象的操作!");

    }
}
  1. UserService.java
@Service("uService")
public class UserService {

    @Resource(name = "uManager")
    private UserManager manager;

    public void service() {
        System.out.println("调用Service");
        manager.addUser();
    }
}
  1. UserAction.java
@Controller("uAction")
//@Scope("prototype") //多例
public class UserAction {

    @Resource(name = "uService")
    private UserService service;

    public String execute() {
        System.out.println("调用Action");
        service.service();
        return "success";
    }
}
  1. MainClass.java
public static void main(String[] args) {

    BeanFactory factory = new ClassPathXmlApplicationContext(
            "applicationContext.xml");

    // UserAction ua = (UserAction) factory.getBean("userAction");

    UserAction ua = (UserAction) factory.getBean("uAction");
    System.out.println(ua);

    ua = (UserAction) factory.getBean("uAction");
    System.out.println(ua);

    ua = (UserAction) factory.getBean("uAction");
    System.out.println(ua);

    System.out.println(ua.execute());
}

关注点分离和静态代理

  1. 关注点分离
Me.java
@Component
public class Me {

    @Resource
    private Servant servant;

    public void dowork() {

        makeBeds();// 关注点
        dress();// 关注点
        haveAMeal();// 关注点

        System.out.println("我工作……");// 真正的业务

        haveAMeal();// 关注点
        makeBeds();// 关注点
        undress();// 关注点

    }

    // 使用面向过程编程
    private void makeBeds() {
    System.out.println("叠被子");
    }

    private void dress() {
    System.out.println("穿衣服");
    }

    private void haveAMeal() {
    System.out.println("吃饭");
    }

    private void undress() {
    System.out.println("脱衣服");
    }
}
  1. 静态代理

a) MeInterface.java

public interface MeInterface {

    public abstract void dowork();
}

b) Me.java

@Component("me")
public class Me implements MeInterface {
    @Override
    public void dowork() {

        System.out.println("我工作……");// 真正的业务
    }
}

c) Servant.java

@Component("ser")
public class Servant {
    public void work1() {
        this.makeBeds();
        this.dress();
        this.haveAMeal();
    }

    public void work2() {
        this.haveAMeal();
        this.puChuang();
        this.undress();
    }

    public void makeBeds() {
        System.out.println("叠被子");
    }

    public void dress() {
        System.out.println("穿衣服");
    }

    public void haveAMeal() {
        System.out.println("吃饭");
    }

    public void undress() {
        System.out.println("脱衣服");
    }

    public void puChuang() {
        System.out.println("铺床");
    }
}

d) MyProxy.java

@Component
public class MyProxy implements MeInterface {

    @Resource(name = "me")
    private Me target;// 真正的目标对象,我们这个代理服务的对象

    @Resource(name="ser")
    private Servant servant;

    @Override
    public void dowork() {

        servant.work1();

        target.dowork();

        servant.work2();
    }
}

e) 使用代理

@Test
public void test() {

    BeanFactory factory = new ClassPathXmlApplicationContext(
            "applicationContext.xml");
    
    MeInterface me = (MeInterface) factory.getBean(MyProxy.class);
    //代理将我的关注点做好再让我去工作……
    me.dowork();
}

动态代理和横切关注点分离

  1. DynamicProxyFactory.java
public class DynamicProxyFactory implements InvocationHandler {

    private DynamicProxyFactory() {
    }

    // 自己new的没法注入,通过创建代理的newInstance方法注入
    private Servant servant;
    private Object target;

    /**
     * 创建代理的静态方法
     */
    public static Object newInstance(Object target, Servant servant) {
        DynamicProxyFactory dp = new DynamicProxyFactory();
        dp.servant = servant;
        dp.target = target;
        return Proxy.newProxyInstance(target.getClass().getClassLoader(),
                target.getClass().getInterfaces(), dp);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {

        servant.work1();

        Object o = // 调用动态代理类代理的目标对象上的方法(真正要调用的业务方法)
        method.invoke(target, args);

        servant.work2();
        return o;
    }
}
  1. applicationContext.xml


   
    
    

    
    

    
         
         
    
        
         
         
    
  1. 使用动态代理
@Test
public void test() {
    BeanFactory factory = new ClassPathXmlApplicationContext(
            "applicationContext.xml");
    
    MeInterface me = (MeInterface) factory.getBean("my");
    //代理将我的关注点做好再让我去工作……
    me.dowork();
    
    System.out.println("--------------------");
    HeInterface he = (HeInterface) factory.getBean("h");
    he.hedowork();
}

利用Spring的AspectJ创建动态代理分离横切关注点

  1. 用到的包
    aspectjrt.jar   Spring的依赖包
    aspectjweaver.jar   Spring的依赖包
    aopalliance.jar aop
    spring-aop-3.2.0.M1.jar aop支持类
  1. applicationContext.xml



    
    

    
    

    
    
  1. AspClass.java
/**
* 切面类
*/
@Aspect
@Component
public class AspClass {

    @Resource(name = "ser")
    private Servant servant;

    @Before("execution(* com.ashmit.spring.MeInterface.*(..))||execution(* com.ashmit.spring.HeInterface.*(..))")
    void before() {
        servant.work1();
    }

    @After("execution(* com.ashmit.spring.MeInterface.*(..))||execution(* com.ashmit.spring.HeInterface.*(..))")
    void after() {
        servant.work2();
    }
}
  1. 使用Spring的AspectJ创建的动态代理
@Test
public void test() {
    BeanFactory factory = new ClassPathXmlApplicationContext(
            "applicationContext.xml");
    
    MeInterface me = (MeInterface) factory.getBean("me");
    //代理将我的关注点做好再让我去工作……
    me.dowork();
    
    System.out.println("--------------------");
    HeInterface he = (HeInterface) factory.getBean("he");
    he.hedowork();
}
  1. 可以不使用切面类AspClass

a) Servant01

@Aspect
@Component
public class Servant01 implements Ordered {

    @Before("execution(* com.ashmit.spring.MeInterface.*(..))||execution(* com.ashmit.spring.HeInterface.*(..))")
    public void makeBeds() {
        System.out.println("叠被子");
    }

    @Override
    public int getOrder() {
        return 0;
    }
}

b) Servant02

@Aspect
@Component
public class Servant02 implements Ordered{

    @Before("execution(* com.ashmit.spring.MeInterface.*(..))||execution(* com.ashmit.spring.HeInterface.*(..))")
    public void dress() {
        System.out.println("穿衣服");
    }

    @Override
    public int getOrder() {
        // TODO Auto-generated method stub
        return 1;
    }
}

c) Servant03

@Aspect
@Component
public class Servant03 implements Ordered {

    @Before("execution(* com.ashmit.spring.MeInterface.*(..))||execution(* com.ashmit.spring.HeInterface.*(..))")
    public void haveAMeal() {
        System.out.println("吃饭");
    }

    @After("execution(* com.ashmit.spring.MeInterface.*(..))||execution(* com.ashmit.spring.HeInterface.*(..))")
    public void haveAMeal2() {
        System.out.println("吃饭");
    }

    @Override
    public int getOrder() {
        // TODO Auto-generated method stub
        return 2;
    }
}

d) Servant04

@Aspect
@Component
public class Servant04 implements Ordered{

    @After("execution(* com.ashmit.spring.MeInterface.*(..))||execution(* com.ashmit.spring.HeInterface.*(..))")
    public void puChuang() {
        System.out.println("铺床");
    }

    @Override
    public int getOrder() {
        // TODO Auto-generated method stub
        return 1;
    }
}

e) Servant05

@Aspect
@Component
public class Servant05 implements Ordered{

    @After("execution(* com.ashmit.spring.MeInterface.*(..))||execution(* com.ashmit.spring.HeInterface.*(..))")
    public void undress() {
        System.out.println("脱衣服");
    }

    @Override
    public int getOrder() {
        // TODO Auto-generated method stub
        return 0;
    }
}
  1. Around、AfterThrowing等其它Advice

    a) Me.java

    @Component("me")
    public class Me implements MeInterface {
    
    @Override
    public void dowork() {
        if (true)
            throw new RuntimeException("RuntimeException……");
        System.out.println("我工作……");// 真正的业务
    }
    }

b) AspClass.java

/**
* 切面类
*/
@Aspect
@Component
public class AspClass {

    @Resource(name = "ser")
    private Servant servant;

    /**
     * @param 执行方法的东西
     * @return 返回方法的返回值
     */
        //  @Around("execution(* com.ashmit.spring.MeInterface.*(..))||execution(* com.ashmit.spring.HeInterface.*(..))")
        //  public Object test(ProceedingJoinPoint proceeding) {
        //      Object o = null;
        //      try {
        //          servant.work1();
        //          // proceeding.proceed(proceeding.getArgs());
        //          o = proceeding.proceed();
        //          
        //          servant.work2();
        //      } catch (Throwable e) {
        //          // TODO Auto-generated catch block
        //          e.printStackTrace();
        //      }
        //      return o;
        //  }


    @Before("execution(* com.ashmit.spring.MeInterface.*(..))||execution(* com.ashmit.spring.HeInterface.*(..))")
    void before() {
        System.out.println("开始代理……");
        servant.work1();
    }
    @After("execution(* com.ashmit.spring.MeInterface.*(..))||execution(* com.ashmit.spring.HeInterface.*(..))")
    void after() {
        servant.work2();
        System.out.println("结束代理……");
    }
    /**
     * 返回时执行(最后执行)
     */
    @AfterReturning("execution(* com.ashmit.spring.MeInterface.*(..))||execution(* com.ashmit.spring.HeInterface.*(..))")
    void test2() {
        System.out.println("返回……");
    }

    /**
     * 抛异常 注意:不能跟定义了@Around的方法连着用,否则不执行
     */
    @AfterThrowing("execution(* com.ashmit.spring.MeInterface.*(..))||execution(* com.ashmit.spring.HeInterface.*(..))")
    void test3() {
        System.out.println("抛异常……");
    }
}

Spring配置文件中配置切面

  1. AspClass.java
/**
* 切面类
*/
@Component("aspclass")
public class AspClass {

    @Resource(name = "ser")
    private Servant servant;

    void before() {
        servant.work1();
    }

    void after() {
        servant.work2();
    }
}
  1. applicationContext.xml



    
    

    
    

    

    
        
        

        
        
            
        
        
            
        

    

Spring AOP声明式事务

  1. 用到的包
    commons-dbcp.jar    
    commons-pool.jar    
    spring-jdbc-3.2.0.M1.jar    以上dataSource需要
    spring-orm-3.2.0.M1.jar sessionFactory需要
    spring-aop-3.2.0.M1.jar aop支持类
    spring-tx-3.2.0.M1.jar  事物通知
  1. applicationContext.xml



    
    

    
    

    
    
        
        
        
        
    

    
    
        
        
            
                com.ashmit.entity.User
                com.ashmit.entity.Group
            
        
        
            
                hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
                hibernate.show_sql=true
                hbm2ddl.auto=update
                javax.persistence.validation.mode=none
                hibernate.cache.use_second_level_cache=true
                hibernate.cache.use_query_cache=true
    hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory
            
        
    

    
    
        
    

    
    
        
        
            
            
            
            
        
    

    
    
        
        
    
  1. 事务传播特性


    
    
        
        
        
        
        
        
        
    

Spring与Struts框架的集成

  1. 用到的包
struts2-spring-plugin-2.3.4.jar 在Struts文件中
spring-web-3.2.0.M1.jar 在Spring文件中
  1. UserAction.java
@Controller("userAction")
public class UserAction implements ModelDriven {

    private User user = null;

    @Resource(name = "groupService")
    private GroupService groupService = null;

    @Resource(name = "userService")
    private UserService userService = null;

    //各种方法
    ……
}
  1. web.xml



    
    
        org.springframework.web.context.ContextLoaderListener
    

    
    
        contextConfigLocation
        /WEB-INF/applicationContext-*.xml,classpath*:applicationContext-*.xml
    

    ……

BaseDao模式

  1. BaseDao.java
public class BaseDao {

    @Resource(name = "sessionFactory")
    private SessionFactory sessionFactory = null;

    protected Session getSession() {
        return this.sessionFactory.getCurrentSession();
    }
}

OpenSessionInView模式

应对懒加载策略




    
    
        org.springframework.web.context.ContextLoaderListener
    

    
    
        contextConfigLocation
        /WEB-INF/applicationContext-*.xml,classpath*:applicationContext-*.xml
    

    
    
        OpenSessionInViewFilter
        org.springframework.orm.hibernate4.support.OpenSessionInViewFilter
    
    
        OpenSessionInViewFilter
        /*
    

    ……

你可能感兴趣的:(Spring笔记整理)