@ComponentScan在spring中⽆效的原因分析及解决⽅案⽬录
@ComponentScan在spring中⽆效
查了⼤量资料之后,到了原因
@Component和@ComponentScan常规理解
@Component和@ComponentScan的联系
@SpringBootApplication和@ComponentScan,扫描包的区别
@ComponentScan在spring中⽆效
在我实现第⼀个spring AOP程序的时候,我按照主流的推荐,采⽤注解@ComponentScan @Aspect @Before 来实现⼀个切⾯。
让我⼗分纳闷的是。我的程序始终⽆法正确调⽤到通知。⽽且我的通知和主流的毫⽆差别。代码如下:
通知类,其中定义了切⾯:
package com.bfytech.spring_8_bean3;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class Advice {
@Before("execution(* com.bfytech.spring_8_Name(..))")
public void logBeforeFunction() {
System.out.println("function begin");
}
@After("execution(* com.bfytech.spring_8_bean3.Person.*(..))")
public void logAfterFunction() {
System.out.println("function end");
}
}
业务类:
package com.bfytech.spring_8_bean3;
import org.springframework.stereotype.Component;
@Component
public class Person {
private String name;
private int age;
public String getName() {
System.out.println("");
return name;
}
public void setName(String name) {
this.name = name;
System.out.println("");
}
public int getAge() {
System.out.println("");
return age;
}
public void setAge(int age) {
System.out.println("");
this.age = age;
}
}
Bean配置类:
package com.bfytech.spring_8_bean3;
import t.annotation.Bean;
import t.annotation.ComponentScan;
import t.annotation.Configuration;
import t.annotation.EnableAspectJAutoProxy;
@Configuration
@EnableAspectJAutoProxy
@ComponentScan
public class BeanConfig {
@Bean
public Advice advice() {
return new Advice();
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="/schema/beans"
xmlns:xsi="/2001/XMLSchema-instance"
xmlns:p="/schema/p"
xmlns:context="/schema/context"
xmlns:util="/schema/util"
xsi:schemaLocation="/schema/beans /schema/beans/spring-beans-4.1.xsd
/schema/context /schema/context/spring-context-4.3.xsd
/schema/util /schema/util/spring-util-4.3.
xsd">
</beans>
最后的调⽤类App
package com.bfytech.spring_8_bean3;
import t.ApplicationContext;
import t.annotation.AnnotationConfigApplicationContext;
import t.support.FileSystemXmlApplicationContext;
/**
* Hello world!
*
*/
public class App
{
public static void main( String[] args )
{
System.out.println( "Hello World!" );
ApplicationContext context = new FileSystemXmlApplicationContext("l");
Person person = (Person) Bean(Person.class);
person.setName("Tony");
person.setAge(88);
System.out.Name());
System.out.Age());
}
}
郁闷之余。做了⼤量尝试,后来发现在l中添加如下⾏:
<context:component-scan base-package="com.bfytech.spring_8_bean3"></context:component-scan>
之后可以正常把AOP启动起来。
查了⼤量资料之后,到了原因
原来很多资料中把xml配置和注解配置混淆在⼀起了!
当你采⽤xml配置的时候,则l的内容会⽣效。但是前提是你需要采⽤FileSystemXmlApplicationContext 或者ClassPathXmlApplicationContext去读取这个xml,配置才会⽣效!同时@ComponentScan会被忽略!
⽽当你采⽤注解配置的时候,则你应该使⽤AnnotationConfigApplicationContext来加载,这时配置类的中的
spring framework是什么框架的@ComponentScan就会⽣效。
修改代码App.java为
package com.bfytech.spring_8_bean3;
import t.ApplicationContext;
import t.annotation.AnnotationConfigApplicationContext;
import t.support.FileSystemXmlApplicationContext;
/**
* Hello world!
*
*/
public class App
{
public static void main( String[] args )
{
System.out.println( "Hello World!" );
ApplicationContext context = new AnnotationConfigApplicationContext(BeanConfig.class);
Person person = (Person) Bean(Person.class);
person.setName("Tony");
person.setAge(88);
System.out.Name());
System.out.Age());
}
}
运⾏结果正常了!
顺便说,还有⼀个坑。execution表达式因为没有编译时检查,任何标点符号的错误也会在运⾏时忽略(??我很纳闷,为什么不抛异常),所以需要反复检查。⽐如说下⾯的表达式,你觉得有错么?
@Before("execution(* com.bfytech.spring_8_bean3.*.*(**))")
这个表达式是错误的,因为(**)应该是(..).⽽运⾏时这个不会报任何错误。但是切⽚的代码不会运⾏.....
@Component和@ComponentScan常规理解
@Component和@ComponentScan的联系
@Component 这个注解的作⽤是把我们写的bean注⼊到容器中,以供使⽤。
@ComponentScan 注解的作⽤则是扫描包中的bean(⽐如:Spring不知道你定义了某个bean除⾮它知道从哪⾥可以到这个bean,ComponentScan做的事情就是告诉Spring从哪⾥到bean),由你来定义哪些包需要被扫描。
⼀旦你指定了,Spring将会将在被指定的包及其下级包中寻bean,这两个注解进⾏配合使⽤。
@SpringBootApplication和@ComponentScan,扫描包的区别
如果你的其他包都在使⽤了@SpringBootApplication注解的main app所在的包及其下级包,则你什么都不⽤做,SpringBoot 会⾃动帮你把其他包都扫描了如果你有⼀些bean所在的包,不在main app的包及其下级包,那么你需要⼿动加上
@ComponentScan注解并指定那个bean所在的包。
以上为个⼈经验,希望能给⼤家⼀个参考,也希望⼤家多多⽀持。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论