前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ioc和aop扩展

ioc和aop扩展

作者头像
xiaozhangStu
发布2023-05-04 19:17:07
1890
发布2023-05-04 19:17:07
举报
文章被收录于专栏:xiaozhangStuxiaozhangStu

ioc和aop扩展

构造注入

必须提供带参的构造函数

而且配置文件的标签也是不一样的

代码语言:javascript
复制
public interface IUserDao {
    public  void add(User User);
}
public class UserDao implements IUserDao {
    @Override
    public void add(User User) {
​
        System.out.println("加了一个用户对象");
    }
}
public interface IUserservice {
​
    public void addUser(User User);
​
}
public class UserServices implements IUserservice{
    private UserDao dao;
    private String s1;
    private String s2;
    private int i;
​
    @Override
    public void addUser(User User) {
        dao.add(User);
    }
​
    public UserServices(UserDao dao, String s1, String s2, int i) {
        this.dao = dao;
        this.s1 = s1;
        this.s2 = s2;
        this.i = i;
    }
​
    public UserServices() {
    }
}
public class User implements java.io.Serializable {
    private Integer id; // 用户ID
    private String username; // 用户名
    private String password; // 密码
    private String email; // 电子邮件
​
    /* getter & setter */
    public Integer getId() {
        return id;
    }
​
    public void setId(Integer id) {
        this.id = id;
    }
​
    public String getUsername() {
        return username;
    }
​
    public void setUsername(String username) {
        this.username = username;
    }
​
    public String getPassword() {
        return password;
    }
​
    public void setPassword(String password) {
        this.password = password;
    }
​
    public String getEmail() {
        return email;
    }
​
    public void setEmail(String email) {
        this.email = email;
    }
​
}
public class HelloSpringTest {
​
  @Test
    public  void demo(){
    ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
    IUserservice service = (IUserservice) ctx.getBean("userService");
    User user = new User();
    user.setId(1);
    user.setUsername("test");
    user.setPassword("123456");
    user.setEmail("test@xxx.com");
    service.addUser(user);
  }
​
}
代码语言:javascript
复制
<?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:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd">
    <bean id="helloSpring" class="demo.HelloSpring">
        <property name="who">
            <value>Spring</value>
        </property>
    </bean>
    <bean id="userDao" class="dao.impl.UserDao">
​
    </bean>
    <bean id="userService" class="service.UserServices" >
        <constructor-arg>
        <ref bean="userDao"/>
    </constructor-arg>
        <constructor-arg index="1">
            <value >123</value>
        </constructor-arg>
        <constructor-arg index="3" type="int">
            <value >123</value>
        </constructor-arg>
        <constructor-arg index="2">
            <value >123</value>
        </constructor-arg>
    </bean>
    <bean id="loggerUntil" class="aop.LoggerUntil"/>
    <aop:config>
        <aop:pointcut id="pointcut"  expression="execution(  public void addUser(pojo.User))"/>
        <aop:aspect ref="loggerUntil">
            <aop:before method="before" pointcut-ref="pointcut"/>
            <aop:after-returning method="afterReturning" pointcut-ref="pointcut" returning="result"/>
        </aop:aspect>
    </aop:config>
   <!-- <aop:aspectj-autoproxy proxy-target-class="true"/>-->
</beans>
代码语言:javascript
复制
<constructor-arg index="1" type="int">
    参数位置和参数类型
与设值注入进行对比
设值注入

通过setter访问器实现

灵活性好,但setter方法数量较多

时效性差

通过无参构造实例化

构造注入

通过构造方法实现

灵活性差,仅靠重载限制太多

时效性好

通过匹配的构造方法实例化,但建议保留无参构造

p命名空间

特点

使用属性而不是子元素的形式配置Bean的属性,从而简化了配置代码

用法

使用前要先要在Spring配置文件中引入p命名空间

代码语言:javascript
复制
xmlns:p="http://www.springframework.org/schema/p"

对于直接量(基本数据类型、字符串)属性:p:属性名="属性值" 对于引用Bean的属性:p:属性名-ref="Bean的id"

代码语言:javascript
复制
<bean id="user" class="pojo.User" p:email="1020222@qq.com" p:id="1" p:password="123" p:username="张三">
</bean>
​

注入不同数据类型

类型

方式

引用Bean

使用<ref>标签实现

注意bean属性和 local 属性的区别

使用内部Bean(其他地方都没法使用)

<property name="dao">

<bean class="dao.impl.UserDaoImpl"/></property>

注入集合类型的属性

分别使用<list>、<set>、<map>、<props>标签实现

注入null 和空字符串值

使用<null/>注入null 值

使用<value></value>注入空字符串值

注入直接量

使用<value>标签实现 注意特殊字符的处理

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
    <bean id="entity" class="entity.TestEntity">
        <!-- 使用<![CDATA[]]>标记处理XML特 殊字符 -->
        <property name="specialCharacter1">
            <value><![CDATA[P&G]]></value>
        </property>
        <!-- 把XML特殊字符替换为实体引用 -->
        <property name="specialCharacter2">
            <value>P&amp;G</value>
        </property>
        <!-- 定义内部Bean -->
        <property name="innerBean">
            <bean class="entity.User">
                <property name="username">
                    <value>Mr. Inner</value>
                </property>
            </bean>
        </property>
        <!-- 注入List类型 -->
        <property name="list">
            <list>
                <!-- 定义List中的元素 -->
                <value>足球</value>
                <value>篮球</value>
            </list>
        </property>
        <!-- 注入数组类型 -->
        <property name="array">
            <list>
                <!-- 定义数组中的元素 -->
                <value>足球</value>
                <value>篮球</value>
            </list>
        </property>
        <!-- 注入Set类型 -->
        <property name="set">
            <set>
                <!-- 定义Set或数组中的元素 -->
                <value>足球</value>
                <value>篮球</value>
            </set>
        </property>
        <!-- 注入Map类型 -->
        <property name="map">
            <map>
                <!-- 定义Map中的键值对 -->
                <entry>
                    <key>
                        <value>football</value>
                    </key>
                    <value>足球</value>
                </entry>
                <entry>
                    <key>
                        <value>basketball</value>
                    </key>
                    <value>篮球</value>
                </entry>
            </map>
        </property>
        <!-- 注入Properties类型 -->
        <property name="props">
            <props>
                <!-- 定义Properties中的键值对 -->
                <prop key="football">足球</prop>
                <prop key="basketball">篮球</prop>
            </props>
        </property>
        <!-- 注入空字符串值 -->
        <property name="emptyValue">
            <value></value>
        </property>
        <!-- 注入null值 -->
        <property name="nullValue">
            <null/>
        </property>
    </bean>
</beans>
​
​

异常抛出增强

特点

在目标方法抛出异常时织入增强处理 可拔插的异常处理方案

代码语言:javascript
复制
 public void throwex() throws Exception {
​
        throw new Exception("人造异常");
    }
    
public void afterThrowing(JoinPoint jp,Exception e){
        System.out.println("调用 " + jp.getTarget() + " 的 " + jp.getSignature().getName()
                + " 方法。方法入参:" + Arrays.toString(jp.getArgs())+e.getMessage());
        //log.info(""+jp.getTarget()+jp.getSignature()+ Arrays.toString(jp.getArgs()));
    }  
代码语言:javascript
复制
<aop:config>
        <aop:pointcut id="pointcut"  expression="execution(  public void *(..))"/>
        <aop:aspect ref="loggerUntil">
            <aop:before method="before" pointcut-ref="pointcut"/>
            <aop:after-returning method="afterReturning" pointcut-ref="pointcut" returning="result"/>
            <aop:after-throwing method="afterThrowing" pointcut-ref="pointcut" throwing="e"/>
        </aop:aspect>
    </aop:config>

最终增强

特点

无论方法是否抛出异常,都会在目标方法最后织入增强处理,即:该增强都会得到执行 类似于异常处理机制中finally块的作用,一般用于释放资源 可以为各功能模块提供统一的,可拔插的处理方案

用法与before类似

代码语言:javascript
复制
<aop:after>

环绕增强

目标方法前后都可织入增强处理 功能最强大的增强处理 可获取或修改目标方法的参数、返回值,可对它进行异常处理,甚至可以决定目标方法是否执行

代码语言:javascript
复制
<aop:around>
代码语言:javascript
复制
public void around(ProceedingJoinPoint jp){
        System.out.println("调用 " + jp.getTarget() + " 的 " + jp.getSignature().getName()
                + " 方法。方法入参:" + Arrays.toString(jp.getArgs()));
        try {
             Object result = jp.proceed();
            System.out.println("调用 " + jp.getTarget() + " 的 " + jp.getSignature().getName()
                    + " 方法。方法返回值:" + result);
        } catch (Throwable e) {
            System.out.println("调用 " + jp.getTarget() + " 的 " + jp.getSignature().getName()
                    + " 方法。方法入参:" + Arrays.toString(jp.getArgs())+e.getMessage());
            e.printStackTrace();
        }finally {
            System.out.println("最终");
        }
    }

注解实现IOC

解释

注解方式将Bean的定义信息和Bean实现类结合在一起,简化配置

@Component:实现Bean组件的定义 @Repository :用于标注DAO类 @Service :用于标注业务类 @Controller :用于标注控制器类

代码语言:javascript
复制
@Repository("userDao") 
public class UserDaoImpl implements UserDao {
    …
}
与在XML配置文件中编写
<bean id="userDao" 
class="dao.impl.UserDaoImpl" /> 
等效
​
使用注意事项

要在配置文件头部加相应信息,并且开启扫描

代码语言:javascript
复制
<?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:aop="http://www.springframework.org/schema/aop"
       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/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.2.xsd">
    <bean id="helloSpring" class="demo.HelloSpring">
        <property name="who">
            <value>Spring</value>
        </property>
    </bean>
​
    <context:component-scan base-package="service,dao" />
​
​
​
​
</beans>
@Autowired

使用@Autowired注解实现Bean的自动装配,默认按类型匹配,可以使用@Qualifier指定Bean的名称

代码语言:javascript
复制
@Service("userService")
public class UserServices implements IUserservice{
​
    @Autowired
    private UserDao dao;
​
​
    @Override
    public void addUser(User User) {
        dao.add(User);
    }
    public void throwex() throws Exception {
​
        throw new Exception("人造异常");
    }
    public UserServices(UserDao dao) {
​
    }
​
    public UserServices() {
    }
}
​
@Resource

注解实现组件装配,默认按名称匹配

代码语言:javascript
复制
@Service("userService") 
public class UserServiceImpl implements UserService { 
    @Resource(name = "userDao")
    private UserDao dao; 
    …… 
}

注解配置切面

@Aspect

@Pointcut

@Before

@AfterReturning

@AfterThrowing

@Around

代码语言:javascript
复制
@Component("loggerUntil")
@Aspect
public class LoggerUntil {
   private static Logger log = Logger.getLogger(LoggerUntil.class);
​
   @Pointcut("execution(* service.UserServices.*(..))")
   public void pointcut(){};
​
   @Before("pointcut()")
    public void before(JoinPoint jp){
        System.out.println("调用 " + jp.getTarget() + " 的 " + jp.getSignature().getName()
                + " 方法。方法入参:" + Arrays.toString(jp.getArgs()));
        //log.info(""+jp.getTarget()+jp.getSignature()+ Arrays.toString(jp.getArgs()));
    }
    @AfterReturning(pointcut = "pointcut()",returning = "result")
    public void afterReturning(JoinPoint jp,Object result){
        System.out.println("调用 " + jp.getTarget() + " 的 " + jp.getSignature().getName()
                + " 方法。方法返回值:" + result);
        //log.info(""+jp.getTarget()+jp.getSignature()+result);
    }
    @AfterThrowing(pointcut = "pointcut()",throwing = "e")
    public void afterThrowing(JoinPoint jp,Exception e){
        System.out.println("调用 " + jp.getTarget() + " 的 " + jp.getSignature().getName()
                + " 方法。方法入参:" + Arrays.toString(jp.getArgs())+e.getMessage());
        //log.info(""+jp.getTarget()+jp.getSignature()+ Arrays.toString(jp.getArgs()));
    }
    @Around("pointcut()")
    public void around(ProceedingJoinPoint jp){
        System.out.println("调用 " + jp.getTarget() + " 的 " + jp.getSignature().getName()
                + " 方法。方法入参:" + Arrays.toString(jp.getArgs()));
        try {
             Object result = jp.proceed();
            System.out.println("调用 " + jp.getTarget() + " 的 " + jp.getSignature().getName()
                    + " 方法。方法返回值:" + result);
        } catch (Throwable e) {
            System.out.println("调用 " + jp.getTarget() + " 的 " + jp.getSignature().getName()
                    + " 方法。方法入参:" + Arrays.toString(jp.getArgs())+e.getMessage());
            e.printStackTrace();
        }finally {
            System.out.println("最终");
        }
    }
}
​
代码语言:javascript
复制
<?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:aop="http://www.springframework.org/schema/aop"
       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/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.2.xsd">
    <bean id="helloSpring" class="demo.HelloSpring">
        <property name="who">
            <value>Spring</value>
        </property>
    </bean>
​
    <context:component-scan base-package="service,dao,aop" />
​
    <aop:aspectj-autoproxy />
​
​
​
</beans>
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-02-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • ioc和aop扩展
    • 构造注入
      • p命名空间
        • 注入不同数据类型
          • 异常抛出增强
            • 最终增强
              • 环绕增强
                • 注解实现IOC
                  • 注解配置切面
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档