Spring构造注入注解注入&AOP

一、依赖注入
1.导包

<?xml version="1.0" encoding="UTF-8"?>


4.0.0

<groupId>cn.itsource</groupId>
<artifactId>spring-day2</artifactId>
<version>1.0-SNAPSHOT</version>

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>4.2.5.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>4.2.5.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aop</artifactId>
        <version>4.2.5.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>4.2.5.RELEASE</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.8.8</version>
    </dependency>


    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
</dependencies>

<build>
    <resources>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.xml</include>
            </includes>
        </resource>
       <resource>
           <directory>src/test/java</directory>
           <includes>
               <include>**/*.xml</include>
           </includes>
       </resource>
    </resources>
</build>

2.构造参数注入
方案一:根据构造器参数的顺序(索引)
!-- 按照索引注入,索引开始为0 -->




1
2
3
4
5
方案二:根据构造器参数的名称

1 2 3 4 5 方案三:根据构造器的类型注入 1 2 3 4 5 3.数组 简写 1 .完整写法 xxx yyy zzz 1 2 3 4 5 6 7 二、全注解配置 1.配置context命名空间 <?xml version="1.0" encoding="UTF-8"?>

2.第一步:配置让Spring扫描类与支持注解

<context:component-scan base-package=“cn.itsource._03_anno” />

<context:annotation-config />

3.第二步:在类里面加上注解
.Dao

@Repository
public class UserDao {
public void save(){
System.out.println(“保存数据xxxx…”);
}
}

.Service

@Service
public class UserService {
@Autowired
private UserDao userDao;
public void save(){
userDao.save();
}
}

.Action

/**
Spring 的Controller 实例化默认是单例.
每次请求 controller 就会只使用这一个对象.
*/
@Controller
@Scope(“prototype”)//使用Spring的@Scope(“prototype”)注解,让单例变成多例.
public class UserAction {
@Autowired
private UserService userService;
public String save(){
userService.save();
return “success”;
}
}

4.注解配置bean的名称
4.1.接口有两个实现(可能性比较少)
成之后,大家注意,现在的配置还有一个问题,比如说我按真实情况来一个Dao接口,然后这个接口有两个实现,现在就会出问题
IUserDao (UserJdbcDaoImpl/UserJpaDaoImpl)
而我们声明的时候就是使用了IUserDao
@Service
public class UserService {
@Autowired
private IUserDao userDao;
public void save(){
userDao.save();
}
}

此时会就出错:因为Spring不知道你用的是哪一个dao的实现

4.2.解决的方案:为dao生成的bean加上名称,我们在调用的时候确定名称即可。
@Repository(“userJdbcDao”)
public class UserJdbcDaoImpl implements IUserDao{
public void save(){
System.out.println(“保存数据xxxx…”);
}
}
@Repository(“userJpaDao”)
public class UserJpaDaoImpl implements IUserDao{
public void save(){
System.out.println(“保存数据xxxx…”);
}
}

5.调用名称两套方案:
方案一:使用@Autowired
@Service
public class UserService {
@Autowired
@Qualifier(“userJdbcDao”)
private IUserDao userDao;
public void save(){
userDao.save();
}
}

方案二:使用@Resource
@Service
public class UserService {
@Resource(name=“userJpaDao”)
private IUserDao userDao;
public void save(){
userDao.save();
}
}

如果你用的是Spring的注解,尽量全部使用Spring的标签
三、Spring的AOP
1.AOP概述
定义: 面向切面编程(面向方面编程)
AOP可以用于事务管理,日志管理,性能监测等地方
AOP应用场景:
咱们写代码都知道,如果多个类出现了相同的代码,就应该抽取一个父类,然后把这些公共的代码都写在父类中。
比如说老鹰,鸽子,麻雀,它们都可以翱翔于天际,
2.Xml版实现AOP
1.添加jar文件
aop,aspects
spring-framework-4.1.2.RELEASE-dependencies\org.aopalliance\com.springsource.org.aopalliance\1.0.0\com.springsource.org.aopalliance-1.0.0.jar

spring-framework-4.1.2.RELEASE-dependencies\org.aspectj\com.springsource.org.aspectj.weaver\1.6.8.RELEASE\com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar

2.添加aop命名空间
xmlns:aop=“http://www.springframework.org/schema/aop”
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd

spring.xml

<?xml version="1.0" encoding="UTF-8"?>

<!-- 业务增强的bean -->
<bean id="transactionManager" class="cn.itsource._09_SpringAOP_XML.transaction.TransactionManager"/>

<!-- 被代理对象 -->
<bean id="userServiceImpl" class="cn.itsource._09_SpringAOP_XML.service.UserServiceImpl"></bean>

<!--
    xml配置AOP
-->
<aop:config>
    <!--
        expression 表达式
        声明一个切点【何时何地】
            第一个星号:表示任意返回类型
            cn.itsource._09_SpringAOP_XML.service:包名称
            包名称后面的两个点..:两个点表示当前包或者当前包的子包,不限制包的级别
            第二个星号:任意类名称
            第三个星号:任意方法名称
            (..):任意参数列表
    -->
    <aop:pointcut id="myPointcut" expression="execution(* cn.itsource._09_SpringAOP_XML.service..*.*(..))"/>
    <!-- 切面通知:要做什么 业务逻辑增强 -->
    <aop:aspect ref="transactionManager">
        <!--
            aop:before 前置通知:表示在你调用myPointcut指向的方法之前调用 transactionManager的bean对象的begin方法
        -->
        <!--<aop:before method="begin" pointcut-ref="myPointcut"/>-->
        <!-- aop:after-returning 后置通知 -->
        <!--<aop:after-returning method="commit" pointcut-ref="myPointcut"/>-->
        <!-- aop:after-throwing 异常通知 相当于catch语句块内部执行的事务回滚 -->
        <!-- <aop:after-throwing method="rollback" pointcut-ref="myPointcut"/>-->
        <!-- aop:after 最终通知 相当于finally语句块内部要执行的关闭资源等逻辑代码 -->
        <!--<aop:after method="finalM" pointcut-ref="myPointcut"/>-->

        <!-- aop:around 环绕通知【推荐使用】,用来代替上面的四个通知,自定义增强业务逻辑 -->
        <aop:around method="around" pointcut-ref="myPointcut"/>

    </aop:aspect>
</aop:config>

service

public interface IUserService {

void test();

void add();

}

@Service
public class UserServiceImpl implements IUserService {
@Override
public void add() {
//int i = 10/0;
System.out.println(“add方法”);
}
@Override
public void test() {
System.out.println(“11111111111”);
}
}

public class TransactionManager {

public void begin(){
    System.out.println("开启事务");
}

public void commit(){
    System.out.println("提交事务");
}

public void rollback(){
    System.out.println("事务回滚");
}

public void finalM(){
    System.out.println("释放资源");
}

/**
 * 环绕通知的业务增强:自定义增强业务逻辑
 * @param joinPoint
 * @return
 */
public Object around(ProceedingJoinPoint joinPoint){
    Object obj = null;
    try {
        //执行目标方法之前 开启事务
        this.begin();

        //执行目标方法
        obj = joinPoint.proceed();

        //执行目标后 提交事务
        this.commit();
    } catch (Exception e) {
        e.printStackTrace();
        //事务回滚
        this.rollback();
    } catch (Throwable throwable) {
        throwable.printStackTrace();
        //事务回滚
        this.rollback();
    } finally {
        //关闭资源
        this.finalM();
    }
    return obj;
}

}

测试

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(“classpath:cn/itsource/_09_SpringAOP_XML/test/spring.xml”)
public class SpringAOPTest {

@Autowired
private IUserService userService;

@Test
public void test() throws Exception {
    System.out.println(userService);
    System.out.println(userService.getClass());//com.sun.proxy.$Proxy15
    userService.test();
    userService.add();
}

}

3.注解版
spring.xml

<?xml version="1.0" encoding="UTF-8"?>

<!-- 扫描包 -->
<context:component-scan base-package="cn.itsource._10_SpringAOP_Annotation"/>

<!-- 开启注解支持【默认就是开启的】 -->
<context:annotation-config/>

<!-- 自动生成代理对象 -->
<aop:aspectj-autoproxy/>

service层同上

TransactionManager:

package cn.itsource._10_SpringAOP_Annotation.transaction;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

@Component
@Aspect//@Aspect 表示当前类是一个切面
public class TransactionManager {

//自定义一个切点【代替了xml配置的aop:pointcut标签】
@Pointcut("execution(* cn.itsource._10_SpringAOP_Annotation.service..*.*(..))")
public void aaa(){}

/**
 *  aaa()相当于xml配置文件的aop:pointcut标签的id属性
 */
//@Before("aaa()")
public void begin(){
    System.out.println("开启事务");
}

//@AfterReturning("aaa()")
public void commit(){
    System.out.println("提交事务");
}

public void rollback(){
    System.out.println("事务回滚");
}

public void finalM(){
    System.out.println("释放资源");
}

/**
 * 环绕通知的业务增强:自定义增强业务逻辑
 * @param joinPoint
 * @return
 */
@Around("aaa()")
public Object around(ProceedingJoinPoint joinPoint){
    Object obj = null;
    try {
        //执行目标方法之前 开启事务
        this.begin();

        //执行目标方法
        obj = joinPoint.proceed();

        //执行目标后 提交事务
        this.commit();
    } catch (Exception e) {
        e.printStackTrace();
        //事务回滚
        this.rollback();
    } catch (Throwable throwable) {
        throwable.printStackTrace();
        //事务回滚
        this.rollback();
    } finally {
        //关闭资源
        this.finalM();
    }
    return obj;
}

}

测试

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(“classpath:cn/itsource/_10_SpringAOP_Annotation/test/spring.xml”)
public class SpringAOPTest {

@Autowired
private IUserService userService;

@Test
public void test() throws Exception {
    System.out.println(userService);
    System.out.println(userService.getClass());//com.sun.proxy.$Proxy15
    //userService.test();
    userService.add();
}

}

总结
AOP是面向切面编程,是对咱们OOP的一个补充,Spring的Aop允许咱们在方法的前后加上相应的功能增强。
Spring的Aop是使用代理模式完成的,如果是有接口的类,使用JDK代理模式,如果没有接口的类,使用CGLIB代理模式。
咱们自己使用AOP太麻烦,Spring让我们通过简单的配置即可完成AOP。
第一种配置:XML 第二种配置:注解
配置的时候注意找到何时(方法前后,异常),何地(哪些类的哪些方法),做什么(安全中是添加事务)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值