Spring2.5学习笔记 [贰]

11_用@Resource注解完成属性装配 & 12_编码剖析@Resource注解的实现原理

(2009-12-30  11:20:23)

 

编码解析实现原理日后补充 

 

使用Field注入(用于注解方式)

 

手工注入依赖对象,有两种方式。


1、在配置文件中使用setter方法注入

 


2、使用@Autowired或@Resource注解方式,需要在配置文件中配置如下信息:


<?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:context="
http://www.springframework.org/schema/context"      
       xsi:schemaLocation="
http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
         
          <context:annotation-config/>

</beans>

 

注解在spring安装目录的lib/j2ee/common-annotations.jar

 

@Resource 默认按照名称注入,当找不到名称匹配的bean才会按照类型注入。(推荐使用)
@Autowired默认按照类型注入。

 

注解注入代码量少,推荐使用。

 

 

一个完整的例子如下

 

1、beans.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:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"> <context:annotation-config/> <bean id="personDao" class="com.nbchina.service.impl.PersonDaoBean"/> <bean id="personService" class="com.nbchina.service.impl.PersonServiceBean"/> </beans>

 


2、PersonServiceBean.java 文件

 

 

package com.nbchina.service.impl; import javax.annotation.Resource; import com.nbchina.service.PersonDao; import com.nbchina.service.PersonService; public class PersonServiceBean implements PersonService { @Resource private PersonDao personDao; public void save(){ personDao.add(); } }

 

 

3、SpringTest.java文件

 

 

package junit.test; import org.junit.BeforeClass; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.nbchina.service.PersonService; public class SpringTest { @BeforeClass public static void setUpBeforeClass() throws Exception { } @Test public void instanceSpring(){ ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml"); PersonService personService=(PersonService) ctx.getBean("personService"); personService.save(); } }

 

 

 

 

 

 

  

 

13_@Autowire注解与自动装配

(2009-12-30  13:55:23)

 

 

 

Autowired注解是按类型装配依赖对象,默认情况下要求依赖对象必须存在。如果允许null值,可以设置它required属性为false.

若想使用按名称装配,则可以结合@Qualifier


例如:

@Autowired @Qualifier("personDao") private PersonDao personDao;

@Autowired(required=false) private PersonDao personDao;

 

 

自动装配形式。了解他,但不推荐使用。

 

<bean id="" class="" autowire="byType"/>


autowire属性如下:
byType:按类型装配
byName:按名称装配
constructor:与byType方式类似,不同之处在于它应用于构造器函数。
autodetect:通过自省机制来决定是使用constructor还是byType方式进行自动装配。若发现默认的构造器,则使用byType.

 

 

  

 

14_让Spring自动扫描和管理Bean

(2009-12-30  15:33:23)

 

 

spring2.5为引入了组件自动扫描机制,可以在类路径下寻找标注了@Component、@Service、@Controller、@Repository注解的类,把这些类纳入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:context="http://www.springframework.org/schema/context"      
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
         
          <context:component-scan base-package="com.nbchina"/>


</beans>

 

@Service用于标注业务层组件。  @Controller用于标注控制层组件,如struts中的action。
@Repository用于标注数据访问组件,即DAO组件。  @Component泛指组件,当组件不好归类的时候,可以用这个注解进行标注。

@Service("name") 可以标注名称

@Scope("prototype") 指定作用域


例如

1、


@Service("name") @Scope("prototype") public class PersonServiceBean implements PersonService { private PersonDao personDao; public void save(){ personDao.add(); } }

 

2、


@PostConstruct 指定初始化方法 @Service("name") @Scope("prototype") public class PersonServiceBean implements PersonService { private PersonDao personDao; @PostConstruct public void init(){ System.out.println("初始化"); } public void save(){ personDao.add(); } }

 

 

3、


@PreDestroy 指定关闭资源方法 @Service("name") public class PersonServiceBean implements PersonService { private PersonDao personDao; @PreDestroy public void destory(){ System.out.println("关闭资源"); } public void save(){ personDao.add(); } }

 

 

 

 

  

 

15_使用JDK中的Proxy技术实现AOP功能&16_使用CGLIB实现AOP功能与AOP概念解释

(2009-12-31 10:01:07)

 

 

 

 

 

 

AOP中的概念

 

Aspect(切面)            指横切性关注点的抽象即为切面,它与类相似,只是两者的关注点不一样。类是对物体的特征的抽象,而切面是横切性关注点的抽象。

Joinpoint(连结点)     指那些被拦截到的点。在spring中,这些点指的是方法,因为spring只支持方法类型的连结点,实际上joinpoint还可以是field或类构造器。

Pointcut(切入点)       指我们要对那些joinpoint连结点进行拦截的定义。

Advice(通知)            指拦截到joinpoint之后所要做的事情就是通知。分为前置通知,后置通知,例外通知,最终通知,环绕通知。

Target(目标对象)      代理的目标对象

Weave(织入)           指将Aspects切面应用到target目标对象并导致proxy代理对象创建的过程。

Introduction(引入)   再不修改类代码的前提下,Introduction引入可以在运行期为类动态的添加一些方法或者field。


首先认识一下,不使用框架实现AOP

 

JDKProxyFactory.java 和 CGlibProxyFactory.java


区别就是一个能实现有接口的类。一个可以实现没有接口的类。

 

实际例子,运用在权限判断

 

 


1、PersonServiceBean.java

 

package com.nbchina.service.impl; import com.nbchina.service.PersonService; public class PersonServiceBean implements PersonService { private String user = null; public PersonServiceBean(){ } public PersonServiceBean(String user){ this.user=user; } public String getPersonName(Integer personid) { System.out.println("我是getPersonName()方法"); return "xxx"; } public void save(String name) { System.out.println("我是save()方法"); } public void update(String name, Integer personid) { System.out.println("我是update()方法"); } public String getUser() { return user; } }

 

 

重构抽取接口。

 

 

2、AOPTest.java

 

 

package junit.test; import org.junit.BeforeClass; import org.junit.Test; import com.nbchina.aop.CGlibProxyFactory; import com.nbchina.aop.JDKProxyFactory; import com.nbchina.service.PersonService; import com.nbchina.service.impl.PersonServiceBean; public class AOPTest { @BeforeClass public static void setUpBeforeClass() throws Exception { } @Test public void proxyTest(){ JDKProxyFactory factory = new JDKProxyFactory(); PersonService service = (PersonService)factory.createProxyIntance(new PersonServiceBean("ddd")); service.save("999"); } @Test public void proxyTest2(){ CGlibProxyFactory factory = new CGlibProxyFactory(); PersonServiceBean service = (PersonServiceBean)factory.createProxyIntance(new PersonServiceBean("ddd")); service.save("999"); } }

 


3、JDKProxyFactory.java

 

 

package com.nbchina.aop; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import com.nbchina.service.impl.*; public class JDKProxyFactory implements InvocationHandler{ private Object targetObject; public Object createProxyIntance(Object targetObject){ this.targetObject = targetObject; return Proxy.newProxyInstance(this.targetObject.getClass().getClassLoader(), this.targetObject.getClass().getInterfaces(),this); } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{ PersonServiceBean bean = (PersonServiceBean) this.targetObject; Object result = null; if(bean.getUser()!=null){ result = method.invoke(targetObject, args); } return result; } }

 

 

4、CGlibProxyFactory.java

 

 

package com.nbchina.aop; import java.lang.reflect.Method; import com.nbchina.service.impl.PersonServiceBean; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; public class CGlibProxyFactory implements MethodInterceptor { private Object targetObject; public Object createProxyIntance(Object targetObject){ this.targetObject = targetObject; Enhancer enhancer= new Enhancer(); enhancer.setSuperclass(this.targetObject.getClass()); enhancer.setCallback(this); return enhancer.create(); } public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { PersonServiceBean bean = (PersonServiceBean) this.targetObject; Object result = null; if(bean.getUser()!=null){ //advice() 前置通知 try { result = methodProxy.invoke(targetObject, args); //afteradvice() 后置通知 } catch (RuntimeException e) { //exceptionadvice() 例外通知 }finally{ //finallyadvice() 最终通知 } } return null; } }

 

 

 

 

 

 

  

 

17_Spring的注解方式实现AOP入门&18_Spring的注解方式实现AOP的细节
&19_Spring配置文件实现AOP&20_aspectj的切入点语法定义细节

 

(2009-12-31 15:01:07)

 

 

 

<?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:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"     
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
      
        <aop:aspectj-autoproxy/><!-- 支持注解方式 -->

 

</beans>

 

AOP一般运用于权限系统或运行期监控


spring提供了两种切面使用方式,实际工作中我们可以选用其中一种:


1、基于XML配置方式进行AOP开发。
2、基于注解方式进行AOP开发。

 

 

@Pointcut("execution(* com.nbchina.service..*.*(..))")
第一个*,代表返回值类型。
第二个..,代表对子包下面的类拦截。
第三个*  代表哪个类。
第四个*  代表哪个方法。
第五个(..) 代表方法参数随意。

例如
@Pointcut("execution(!void com.nbchina.service..*.*(..))")

拦截非void返回类型

 


完整例子,新建一个java项目


1、PersonServiceBean.java

 

 

package com.nbchina.service.impl; import com.nbchina.service.PersonService; public class PersonServiceBean implements PersonService { public String getPersonName(Integer id){ System.out.println("我是getPersonName方法"); return "xxx"; } public void save(String name){ System.out.println("我是save方法"); } public void update(String name, Integer id){ System.out.println("我是update方法"); } }

 

 

重构抽取接口


2、MyInterceptor.java

 

 

package com.nbchina.service; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; /** *切面 */ <!--若基于xml配置方式,去掉@Aspect--> @Aspect public class MyInterceptor { @Pointcut("execution (* com.nbchina.service.impl.PersonServiceBean.*(..))") private void anyMethod(){} //声明一个切入点 // @Before("anyMethod()") //定义前置通知 // public void doAccessCheck(){ // System.out.println("前置通知"); // // } @Before("anyMethod() && args(name)") //定义前置通知,获取 public void doAccessCheck(String name){ System.out.println("前置通知"+ name); } // @AfterReturning("anyMethod()") // public void doAfterReturning(){ // System.out.println("后置通知"); // } @AfterReturning(pointcut="anyMethod()",returning="result") public void doAfterReturning(String result){ System.out.println("后置通知"+result); } @After("anyMethod()") public void doAfter(){ System.out.println("最终通知"); } @AfterThrowing("anyMethod()") public void doAfterThrowing(){ System.out.println("例外通知"); } @Around("anyMethod()") //环绕通知 public Object doBasicProfilling(ProceedingJoinPoint pjp) throws Throwable{ //特别适合做权限 //if(){ System.out.println("进入方法"); Object result = pjp.proceed(); System.out.println("退出方法"); //} return result; } }

 

 


3、beans.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:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"> <aop:aspectj-autoproxy/> <!--基于注解方式 <bean id="myInterceptor" class="com.nbchina.service.MyInterceptor"></bean> <bean id="personService" class="com.nbchina.service.impl.PersonServiceBean"></bean> --> <!--基于xml配置方式 <bean id="personService" class="com.nbchina.service.impl.PersonServiceBean"></bean> <bean id="aspetbean" class="com.nbchina.service.MyInterceptor"></bean> <aop:config> <aop:aspect id="asp" ref="aspetbean"> <aop:pointcut id="mycut" expression="execution(* com.nbchina.service.impl.PersonServiceBean.*(..))" /> <!-- 拦截非void类型的。!非的意思 <aop:pointcut id="mycut" expression="execution(!void com.nbchina.service.impl.PersonServiceBean.*(..))" /> --> <aop:before pointcut-ref="mycut" method="doAccessCheck"/> <aop:after-returning pointcut-ref="mycut" method="doAfterReturuning"/> <aop:after-throwing pointcut-ref="mycut" method="doAfterThrowing"/> <aop:after pointcut-ref="mycut" method="doAfter"/> <aop:around pointcut-ref="mycut" method="doBasicProfiling"/> </aop:aspect> </aop:config> --> </beans>

 

 


4、SpringAOPTest.java

 

 

package junit.test; import org.junit.BeforeClass; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.nbchina.service.PersonService; public class SpringAOPTest { @BeforeClass public static void setUpBeforeClass() throws Exception { } @Test public void interceptorTest(){ ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml"); PersonService personService=(PersonService) ctx.getBean("personService"); personService.save("xxx"); personService.getPersonName(2); } }

你可能感兴趣的:(spring,AOP,bean,object,Class,Autowired)