Spring IOC、AOP的使用笔记

xml的配置

在src目录中创建xml文件,命名自定
在xml中添加代码
<?xml version="1.0" encoding="UTF-8"?>
<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"       
            xmlns="http://www.springframework.org/schema/beans"       
            xsi:schemaLocation="http://www.springframework.org/schema/beans    
            http://www.springframework.org/schema/beans/spring-beans.xsd        
            http://www.springframework.org/schema/context        
            http://www.springframework.org/schema/context/spring-context.xsd        
            http://www.springframework.org/schema/aop        
            http://www.springframework.org/schema/aop/spring-aop.xsd">   
            <!--配置一个bean   相当于创建一个UserService对象-->
            <bean id="userService" class="cn.itcast.service.UserServiceImpl"> 
                    <!--通过IcO(依赖注入)注入-->
                    <property name="name" value="zhangsan"></property>        
            </bean>
</beans>
IoC的使用(案例)

创建IUserService接口

public interface IUserService {   
    public void add();
}

创建UserServiceImpl实现类

public class UserServiceImpl implements IUserService {    
       @Override   
       public void add() {   
            System.out.println("创建用户...");  
       }
}

在beans中添加

<bean id="userService" class="com.gxq.service.UserServiceImpl"></bean>

创建测试类Lesson并添加

@Test   
public void test1(){
    ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");   
    IUserService service= (IUserService) context.getBean("userService");        
    service.add();   
}
从.mxl中获取bean
第一种通过ClassPathXmlApplicationContext获取(常用)
ApplicationContext context = new ClassPathXmlApplicationContext("xml文件名);
UserService userService = (强转为xxx对象) context.getBean("bean中的id值");
userService.add();//调用方法
第二种通过xml文件的真实目录获取
ApplicationContext context = new FileSystemXmlApplicationContext("D:\\spring\\day01_spring1\\src\\beans.xml");
UserService userService = (强转为xxx对象) context.getBean("bean中的id值");
userService.add();//调用方法
第三种使用BeanFactory获取(过时)
BeanFactory factory = new XmlBeanFactory(new 
FileSystemResource("D:\\spring\\day01_spring1\\src\\beans.xml"));
UserService userService = (UserService) factory.getBean("userService");userService.add();
构造方法默认优先执行
Spring内部创建对象的原理
  1. 解析xml文件,获取类名、id、属性
  2. 通过反射,用类型创建对象
  3. 给创建的对象赋值
装配bean的三种方式

第一种方式:new 实现类

<bean id="userService1" class="cn.itcast.service.UserServiceImpl"></bean>

第二种方式:通过静态工厂方法

//    静态工厂中的方法    
public static UserService createUserSerice(){       
    return new UserServiceImpl();   
}

<!--xml中的bean-->
<bean id="userService2" class="静态工厂的位置" factory-method="createUserSerice"></bean>

静态方法调用两次

第三种方式:通过实例工厂方法

//实例工厂中的方法
public UserService createUserSerice(){
    return new UserServiceImpl();
}

<!--xml中的bean-->
<bean id="factory2" class="实例工厂的位置"></bean>
<bean id="userService3" factory-bean="factory2" factory-method="createUserSerice"></bean>

静态方法调用三次
DI依赖注入
<bean id="userService1" class="cn.itcast.service.UserServiceImpl">
    <property name="name" value="zs"></property>//依赖注入
</bean>
bean的作用域

设置方法:scope属性

<bean id="userService1" class="cn.itcast.service.UserServiceImpl" 
scope="prototype"></bean>

singleton:在Spring IoC容器中仅存在一个Bean实例,Bean以单例方式存在,内存地址相同;默认值
prototype:每次从容器中调用Bean时,都返回一个新的实例,即每次调用getBean()时 ,相当于执行new XxxBean(),内存地址不同

bean的生命周期

[外链图片转存失败(img-M4XuH5Ny-1564896745849)(en-resource://database/888:1)]
生命周期图解释
1.instantiate bean对象实例化

2.populate properties 封装属性

3.如果Bean实现BeanNameAware 执行 setBeanName:创建对象的名称

4.如果Bean实现BeanFactoryAware 执行setBeanFactory ,获取Spring容器:bean工厂

5.如果存在类实现 BeanPostProcessor(预处理Bean) ,执行postProcessBeforeInitialization

6.如果Bean实现InitializingBean 执行 afterPropertiesSet :属性赋值完成

7.调用 指定初始化方法 init:自定义初始化方法

8.如果存在类实现 BeanPostProcessor(后处理Bean) ,执行postProcessAfterInitialization

执行业务处理

9.如果Bean实现 DisposableBean 执行 destroy:销毁bean对象

10.调用 指定销毁方法 customerDestroy

11.销毁bean对象(关闭容器):service.getClass().getMethod(“close”).invoke(context);

给对象的属性赋值

方法一:通过构造方法注入(前提是Student中有构造方法)

<bean id="stu" class="cn.itcast.model.Student">
    <constructor-arg name="username" value="zhangsanz"></constructor-arg> 
    <constructor-arg name="password" value="123"></constructor-arg>
</bean>

方法二:通过索引和类型注入

<bean id="stu" class="cn.itcast.model.Student">
    <constructor-arg index="0" value="zangsan"  type="java.lang.String"></constructor-arg>        
    <constructor-arg index="1" value="20" type="int"></constructor-arg>
</bean>


方法三:通过set方法注入

<bean id="stu" class="cn.itcast.model.Student">
    <property name="username" value="zhangsan"></property>
    <property name="password" value="zhangsan"></property>        
    <property name="age" value="20"></property>
</bean>

方法四:p命名空间注入(依赖于set方法)

  1. 在头部加上
xmlns:p="http://www.springframework.org/schema/p"
  1. 注入
<bean id="stu" class="cn.itcast.model.Student" p:username="zs" p:password="ls"  p:age="23"></bean>

spEL

格式:
类型:

#{123}、#{‘jack’} : 数字、字符串

#{beanId}  :另一个bean引用

#{beanId.propName}   :操作数据

#{beanId.toString()} :执行方法

#{T(类).字段|方法} :静态方法或字段

好处:可以调用方法

如:<property name="name" value="#{'zhangsan'.toUpperCase()}"></property>
<property name="pi" value="#{T(java.lang.Math).PI}"></property>

集合的注入
<-- list的注入 -->
<bean id="programmer" class="cn.itcast.model.Programmer">       
    <property name="cars">                
        <list>                        
            <value>领克</value>                        
            <value>凯迪拉克</value>               
        </list>        
    </property>        
<-- set的注入 -->
    <property name="pats">                
        <set>                        
            <value>dudou</value>                       
            <value>kity</value>              
         </set>       
      </property>
<-- map -->
      <property name="house">     
         <map>         
            <entry key="山东" value="碧桂园"></entry>   
            <entry key="北京" value="四合院"></entry>      
         </map>
      </property>
<-- Properties -->
      <property name="mysqlInfos">   
        <props>               
            <prop key="url">mysql:jdbc://localhost:3306/pos</prop>        
            <prop key="root">root</prop>           
            <prop key="password">123456</prop>     
         </props>
        </property>
  </bean>
注解的使用
  1. @Repository(“名称”):dao层

  2. @Service(“名称”):service层

  3. @Controller(“名称”):web层

  4. @Autowired:自动根据类型注入

  5. @Qualifier(“名称”):指定自动注入的id名称

  6. @Resource(“名称”)

  7. @ PostConstruct 自定义初始化方法

  8. @ PreDestroy 自定义销毁方法

在需要创建对象的类开头添加@Component(“id”)

在xml中添加<context:annotation-config/>
<context:component-scan base-package="cn.itcast"/>
创建对象时:

ApplicationContext context = new ClassPathXmlApplicationContext("xxxx.xml");
UserService service = (UserService) context.getBean("id");  //有id时使用
UserService service = (UserService) context.getBean(实现类名.class);

AOP

JDK动态代理

必须是继承接口的实现类才能使用AOP

cglib增强字节码

可以用于继承接口的实现类和普通类

AOP半自动编程

导入AOP联盟jar包:com.springsource.org.aopalliance-1.0.0
AOPjar包:spring-aop-3.2.10.RELEASE
目标类接口

public interface IUserService {  
    public void add();
}

目标类实现类

public class UserServiceImpl implements IUserService {  
    @Override    
    public void add() {    
        System.out.println("创建用户"+name);  
    }
}

测试类

public class Lessin07 { 
    @Test 
    public void test1(){   
    ApplicationContext context = new ClassPathXmlApplicationContext("beans7.xml");  
    IUserService service = (IUserService) context.getBean("sevriceProxy");   
    service.add();   
    }
}

MyAspect切面类

public class MyAspect implements MethodInterceptor {  
    @Override   
    public Object invoke(MethodInvocation mi) throws Throwable {       
        //拦截方法   
        System.out.println("开启事务");    
        //放行     
        Object retObj = mi.proceed();    
        System.out.println("拦截....");    
        System.out.println("提交事务");   
        return retObj;   
    }
}

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"    
    xmlns:p="http://www.springframework.org/schema/p"   
    xmlns:context="http://www.springframework.org/schema/context"     
    xsi:schemaLocation="http://www.springframework.org/schema/beans   
    http://www.springframework.org/schema/beans/spring-beans.xsd      
    http://www.springframework.org/schema/context       
    http://www.springframework.org/schema/context/spring-context.xsd">      
    
    <!--配置userservice-->   
    <bean id="userService" class="com.gxq.service.UserServiceImpl"></bean>   
    <!--配置切面类-->    
    <bean id="myAspect" class="com.gxq.service.MyAspect"></bean>     
    <!--配置代理对象-->   
    <bean id="sevriceProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
        <!--接口-->        
        <property name="interfaces" value="com.gxq.service.IUserService"/>      
        <!--目标对象-->        
        <property name="target" ref="userService"></property>    
        <!--切面类-->    
         <property name="interceptorNames" value="myAspect"></property>   
     </bean>
 </beans>


AOP全自动编程

导入com.springsource.org.aspectj.weaver-1.6.8.RELEASE依赖jar包
在xml头部添加

xmlns:aop="http://www.springframework.org/schema/aop
//在xsi:schemaLocation中
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
<bean id="userService" class="cn.itcast.service.UserServiceImpl"></bean>

<!--  配置切面类对象-->

<bean id="myAspect" class="cn.itcast.service.MyAspect2"></bean>

<!-- 全自动AOP配置 
    1.在bean中配置aop约束 
    2.配置aop:config内容,把切入点和通知结合 proxy-target-class:
        使用cglib实现代理 expression 表达式:*任意  
        execution(*  com.gyf.service.*. *  (..)) :返回值    包名   类名 方法名  参数 -->
        
 <aop:config  proxy-target-class="true">        
 
 <!-- 切入点: expression:表达式   每个service的方法前面都开启事务和结束事务            
        AOP:用于事务配置&日志记录         -->        
        
 <aop:pointcut id="myPointcut" expression="execution (* cn.itcast.service.UserServiceImpl.deleteUser())"/>
 
 <!-- 通知 关联 切入点-->      
 
 <aop:advisor advice-ref="myAspect" pointcut-ref="myPointcut" ></aop:advisor>
 </aop:config>·

AspectJ

导入jar包:spring-aspects-3.2.10.RELEASE
xml中添加代码

<!--配置userservice-->
<bean id="userService" class="com.gxq.service.UserServiceImpl"></bean>
<!--配置切面类-->
<bean id="myAspect3" class="com.gxq.aspect.MyAspect3"></bean>
<!--配置AOP-->
<aop:config>   
    <!--aop指定切面-->    
    <aop:aspect ref="myAspect3">        
    <!--配置切入点-->       
    <aop:pointcut id="myPointcut" expression="execution(* com.gxq.service.UserServiceImpl.*(..))"/> 
    <!--配置前置通知-->
    <!--<aop:before method="myBefore" pointcut-ref="myPointcut"/>-->  
    <!--配置后置通知-->       
    <!--<aop:after-returning method="myAfterReturning" pointcut-ref="myPointcut"/>-->  
    <!--配置环绕通知-->        
    <aop:around method="myAround" pointcut-ref="myPointcut"/>   
    </aop:aspect>
</aop:config>

切面类:

public class MyAspect3 {  
    //前置
    public void myBefore(){    
        System.out.println("前置通知"); 
    }   
    //后置
    //如果service有返回值,则添加Object retValue形参,在xml中添加returning="retValue"属性
    public void myAfterReturning(){   
        System.out.println("后置通知"); 
    }
    //环绕
    public Object myAround(ProceedingJoinPoint pjp) throws Throwable { 
        System.out.println("环绕通知");  
        System.out.println("前置通知");
        //        放行       
        Object retObj = pjp.proceed();       
        System.out.println("后置通知");      
        return retObj;    
    }
}
AspectJ的注解

切面类中添加:@Component和@Aspect两个注解
service类中添加:@Service(“id”)注解
xml文件中代码:

    <context:component-scan base-package="com.gxq"/>
    <aop:aspectj-autoproxy/>

    <aop:config>
    //ref值为切面类名称首字母小写
        <aop:aspect ref="myAspect"></aop:aspect>
    </aop:config>

测试类中代码:

ApplicationContext context = new ClassPathXmlApplicationContext("xml文件名");
IUserService service = (IUserService) context.getBean("serviceID名");
//调用方法
service.add(1);

@Aspect  声明切面,修饰切面类,从而获得 通知。

通知

@Before 前置

@AfterReturning 后置

@Around 环绕

@AfterThrowing 抛出异常

@After 最终

切入点

@PointCut ,修饰方法 private void xxx(){}  之后通过“方法名”获得切入点引用

数据库操作

c3p0 及 JdbcTemplate

导入包:com.springsource.org.apache.commons.dbcp-1.2.2.osgi
com.springsource.org.apache.commons.pool-1.5.3
mysql-connector-java-5.1.37-bin
spring-jdbc-3.2.10.RELEASE
spring-tx-3.2.10.RELEASE

UserDaoImpl继承IUserDao

public class UserDaoImpl implements IUserDao {  
    JdbcTemplate jdbcTemplate = new JdbcTemplate();  
    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {    
        this.jdbcTemplate = jdbcTemplate;   
    }    @Override  
    public void add(User user) {     
        System.out.println("userDao添加用户"+user);    
        jdbcTemplate.update("insert into t_user (username,password) values 
    (?,?)",user.getUsername(),user.getPassword());
    }
}

dao中添加

public class UserDaoImpl implements IUserDao { 
    private JdbcTemplate jdbcTemplate;   
    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {  
        this.jdbcTemplate = jdbcTemplate;  
    }   
    @Override   
    public void add(User user) { 
        jdbcTemplate.update("insert t_user(username,password) values (?,?)",user.getUsername(),user.getPassword());  
    }

c3p0的配置文件.properties

driverClass=com.mysql.jdbc.Driverjdbc
Url=jdbc:mysql:///spring_day04
user=root
password=123456

在xml中添加

<!--JdbcTemplate配置DataSource-->
<!-- <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> 
            <property name="driverClassName" value="com.mysql.jdbc.Driver"/> 
            <property name="url" value="jdbc:mysql:///spring_day04"/>  
            <property name="username" value="root"/>   
            <property name="password" value="123456"/>
        </bean> -->

<!-- c3p0配置DataSource-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">   
    <property name="driverClass" value="${driverClass}"></property>   
    <property name="jdbcUrl" value="${jdbcUrl}"/>  
    <property name="user" value="${user}"/> 
    <property name="password" value="${password}/>
</bean>



<!-- 配置jdbcTemplate -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">  
    <property name="dataSource" ref="dataSource"></property>
</bean>

<!-- 配置dao -->
<bean id="userDao" class="com.gxq.dao.UserDaoImpl"> 
    <property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>

测试类

public void test1(){  
    ApplicationContext context = new ClassPathXmlApplicationContext("beans05.xml");   
    IUserDao userDao = (IUserDao) context.getBean("userDao");  
    User user = new User(); 
    user.setUsername("zzm");   
    user.setPassword("123");   
    userDao.add(user);
}

事务操作

AOP的事务配置

<!--jdbc配置-->
<context:property-placeholder location="classpath:db.properties"></context:property-placeholder>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">   
    <property name="driverClass" value="${driverClass}"></property>  
    <property name="jdbcUrl" value="${jdbcUrl}"/>   
    <property name="user" value="${user}"/>  
    <property name="password" value="${password}"/>
</bean>
<bean id="accountDao" class="com.gxq.dao.Impl.AccoutDaoImpl">    
    <property name="dataSource" ref="dataSource"></property>
</bean>
<!--配置事务管理器-->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
    <!--配置DataSource-->
    <property name="dataSource" ref="dataSource"></property>
</bean>
<!--配置service-->
<bean id="accountService" class="com.gxq.service.AccountService">   
    <property name="accountDao" ref="accountDao"></property>
</bean>
<!--配置通知事务管理器-->
<tx:advice id="txAdvice" transaction-manager="txManager">  
    <!--事务详情: 传播行为  隔离级别-->  
    <tx:attributes>   
        <tx:method name="service中的方法名" propagation="REQUIRED" isolation="DEFAULT"/>
        。
        。可以多个
        。
    </tx:attributes>
</tx:advice>
<!--切入点链接通知事务管理器-->
<aop:config>
    <aop:pointcut id="myPointCut" expression="execution(* com.gxq.service..*.*(..))">
    </aop:pointcut>   
    <aop:advisor advice-ref="txAdvice" pointcut-ref="myPointCut">
    </aop:advisor>
</aop:config>

通过注解进行事务配置
xml中

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">  
    <property name="driverClass" value="${driverClass}"></property>  
    <property name="jdbcUrl" value="${jdbcUrl}"/>   
    <property name="user" value="${user}"/>    
    <property name="password" value="${password}"/>
</bean>
<bean id="accountDao" class="com.gxq.dao.Impl.AccoutDaoImpl">  
    <property name="dataSource" ref="dataSource"></property>
</bean>
<!--配置service-->
<bean id="accountService" class="com.gxq.service.AccountService">   
    <property name="accountDao" ref="accountDao"></property>
</bean>
<!--配置事务管理器-->
<bean id="txManager" 
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">    
    <!--配置DataSource-->
    <property name="dataSource" ref="dataSource"></property>
</bean>
<!--切入点链接通知事务管理器-->
<tx:annotation-driven transaction-manager="txManager"></tx:annotation-driven>

在service中添加@Transactional注解

  1. 属性可以在其后的()中写,不写则为默认值
  2. 根据位置确定作用域,在类名上面写,整个类的所有方法都起作用;在方法名上面写,只有这一个方法起作用

spring Servlet的整合

在src目录中创建applicationContext.xml
并添加spring的配置代码

<?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:p="http://www.springframework.org/schema/p"       
    xmlns:context="http://www.springframework.org/schema/context"    
    xmlns:aop="http://www.springframework.org/schema/aop"       
    xmlns:tx="http://www.springframework.org/schema/tx"       
    xsi:schemaLocation="http://www.springframework.org/schema/beans     
    http://www.springframework.org/schema/beans/spring-beans.xsd       
    http://www.springframework.org/schema/context       
    http://www.springframework.org/schema/context/spring-context.xsd     
    http://www.springframework.org/schema/aop       
    http://www.springframework.org/schema/aop/spring-aop.xsd       
    http://www.springframework.org/schema/tx       
    http://www.springframework.org/schema/tx/spring-tx.xsd">
</beans>

在web.xml中添加

<context-param>   
    <param-name>contextConfigLocation</param-name>    
    <param-value>classpath:applicationContext.xml</param-value>
</context-param>

<listener>    
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener>

servlet

//加载applicationContext.xml文件
ApplicationContext context = 
WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());
//通过bean创建类
userService = (IUserService) context.getBean("userService");
//调用方法
userService.add(username);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值